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/04/30 17:29:13 UTC

[01/50] [abbrv] openmeetings git commit: [OPENMEETINGS-980] wicket-jqueryui version is updated

Repository: openmeetings
Updated Branches:
  refs/heads/master [created] a3379255d


[OPENMEETINGS-980] wicket-jqueryui version is updated


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/e30de20a
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/e30de20a
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/e30de20a

Branch: refs/heads/master
Commit: e30de20a7cb76ff0152d7fb7c0b1c5fa7f5c7ac0
Parents: b744361
Author: Maxim Solodovnik <so...@apache.org>
Authored: Fri Mar 31 14:31:56 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Fri Mar 31 14:31:56 2017 +0000

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e30de20a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 336e6aa..67519ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,7 +41,7 @@
 		<maven.surefire.version>2.19.1</maven.surefire.version>
 		<maven-site.version>3.3</maven-site.version>
 		<wicket.version>8.0.0-SNAPSHOT</wicket.version>
-		<wicketju.version>8.0.0-M4.1</wicketju.version>
+		<wicketju.version>8.0.0-M5</wicketju.version>
 		<wickets.version>8.0.0-SNAPSHOT</wickets.version>
 		<red5-server.version>1.0.9-M6</red5-server.version>
 		<red5-client.version>1.0.9-M6</red5-client.version>


[14/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] basic save is added, code clean-up

Posted by so...@apache.org.
[OPENMEETINGS-551] basic save is added, code clean-up


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/5394af08
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/5394af08
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/5394af08

Branch: refs/heads/master
Commit: 5394af089c42f56d8bd383609564ce08fbd4589b
Parents: 8a900e5
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 5 03:56:54 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 5 03:56:54 2017 +0000

----------------------------------------------------------------------
 .../db/dto/file/FileExplorerItemDTO.java        |  19 ++-
 .../openmeetings/db/dto/room/Whiteboard.java    |  11 ++
 .../web/common/AddFolderDialog.html             |  29 -----
 .../web/common/AddFolderDialog.java             | 107 ----------------
 .../openmeetings/web/common/NameDialog.html     |  29 +++++
 .../openmeetings/web/common/NameDialog.java     | 125 +++++++++++++++++++
 .../web/common/tree/FileTreePanel.java          |   6 +-
 .../web/room/sidebar/RoomFilePanel.java         |   4 +-
 .../web/room/sidebar/RoomSidebar.java           |   4 +-
 .../openmeetings/web/room/wb/WbPanel.html       |   2 +-
 .../openmeetings/web/room/wb/WbPanel.java       |  71 ++++++++---
 .../apache/openmeetings/web/room/wb/fabric.js   |  58 +++++----
 .../openmeetings/web/room/wb/fabric.min.js      |  18 +--
 .../org/apache/openmeetings/web/room/wb/wb.js   |  15 ++-
 .../web/user/profile/MessagesContactsPanel.java |   4 +-
 .../web/user/record/RecordingsPanel.java        |   4 +-
 .../src/main/webapp/WEB-INF/web.xml             |  12 +-
 17 files changed, 305 insertions(+), 213 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/file/FileExplorerItemDTO.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/file/FileExplorerItemDTO.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/file/FileExplorerItemDTO.java
index e384ad5..49f7b23 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/file/FileExplorerItemDTO.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/file/FileExplorerItemDTO.java
@@ -31,7 +31,7 @@ import org.apache.openmeetings.db.entity.file.FileItem.Type;
 
 /**
  * This Object will represent a File on the File-System
- * 
+ *
  * @author sebastianwagner
  *
  */
@@ -44,6 +44,7 @@ public class FileExplorerItemDTO implements Serializable {
 	private String hash;
 	private Long parentId;
 	private Long roomId;
+	private Long groupId;
 	private Long ownerId;
 	private Long size;
 	private String externalId;
@@ -60,6 +61,7 @@ public class FileExplorerItemDTO implements Serializable {
 		hash = f.getHash();
 		parentId = f.getParentId();
 		roomId = f.getRoomId();
+		groupId = f.getGroupId();
 		ownerId = f.getOwnerId();
 		size = f.getSize();
 		externalId = f.getExternalId();
@@ -68,7 +70,7 @@ public class FileExplorerItemDTO implements Serializable {
 		width = f.getWidth();
 		height = f.getHeight();
 	}
-	
+
 	public FileExplorerItem get() {
 		FileExplorerItem f = new FileExplorerItem();
 		f.setId(id);
@@ -76,6 +78,7 @@ public class FileExplorerItemDTO implements Serializable {
 		f.setHash(hash);
 		f.setParentId(parentId != null && parentId > 0 ? parentId : null);
 		f.setRoomId(roomId != null && roomId > 0 ? roomId : null);
+		f.setRoomId(groupId != null && groupId > 0 ? groupId : null);
 		f.setOwnerId(ownerId != null && ownerId > 0 ? ownerId : null);
 		f.setSize(size);
 		f.setExternalId(externalId);
@@ -85,11 +88,11 @@ public class FileExplorerItemDTO implements Serializable {
 		f.setHeight(height);
 		return f;
 	}
-	
+
 	public Long getId() {
 		return id;
 	}
-	
+
 	public void setId(Long id) {
 		this.id = id;
 	}
@@ -126,6 +129,14 @@ public class FileExplorerItemDTO implements Serializable {
 		this.roomId = roomId;
 	}
 
+	public Long getGroupId() {
+		return groupId;
+	}
+
+	public void setGroupId(Long groupId) {
+		this.groupId = groupId;
+	}
+
 	public Long getOwnerId() {
 		return ownerId;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
index c4a3df8..a11a800 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
@@ -140,4 +140,15 @@ public class Whiteboard {
 	public void setSlide(int slide) {
 		this.slide = slide;
 	}
+
+	public JSONObject toJson() {
+		//deep-copy
+		JSONObject json = new JSONObject(new JSONObject(this).toString());
+		json.remove("id"); //filtering
+		JSONObject items = json.getJSONObject("roomItems");
+		for (String uid : items.keySet()) {
+			items.getJSONObject(uid).remove("_src"); //filtering
+		}
+		return json;
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.html
deleted file mode 100644
index 5f9cdd0..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-      http://www.apache.org/licenses/LICENSE-2.0
-    	  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
-  
--->
-<html xmlns:wicket="http://wicket.apache.org">
-<wicket:panel>
-	<form wicket:id="form">
-		<span style="padding-left: 20px; padding-right: 20px;"><wicket:message key="572"/></span><input type="text" wicket:id="title"/>
-		<div wicket:id="feedback"></div>
-		<input type="submit" wicket:id="submit" class="invisible-form-component"/>
-	</form>
-</wicket:panel>
-</html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.java
deleted file mode 100644
index 022ac8d..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/AddFolderDialog.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.common;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.openmeetings.web.app.Application;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.RequiredTextField;
-import org.apache.wicket.markup.html.panel.FeedbackPanel;
-import org.apache.wicket.model.Model;
-
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-
-public abstract class AddFolderDialog extends AbstractFormDialog<String> {
-	private static final long serialVersionUID = 1L;
-	private final DialogButton add = new DialogButton("add", Application.getString(1261));
-	private final DialogButton cancel = new DialogButton("cancel", Application.getString(219));
-	private final Form<String> form;
-	private final FeedbackPanel feedback = new FeedbackPanel("feedback");
-	private final String name;
-	private RequiredTextField<String> title;
-
-	public AddFolderDialog(String id) {
-		this(id, null);
-	}
-
-	public AddFolderDialog(String id, String name) {
-		super(id, Application.getString(1260), Model.of(name));
-		this.name = name;
-		form = new Form<String>("form", getModel()) {
-			private static final long serialVersionUID = 1L;
-			{
-				add(title = new RequiredTextField<>("title", getModel()));
-				title.setLabel(Model.of(Application.getString(572)));
-				add(feedback.setOutputMarkupId(true));
-				add(new AjaxButton("submit") { //FAKE button so "submit-on-enter" works as expected
-					private static final long serialVersionUID = 1L;
-
-					@Override
-					protected void onSubmit(AjaxRequestTarget target) {
-						AddFolderDialog.this.onSubmit(target);
-					}
-
-					@Override
-					protected void onError(AjaxRequestTarget target) {
-						AddFolderDialog.this.onError(target);
-					}
-				});
-			}
-		};
-		add(form.setOutputMarkupId(true));
-	}
-
-	@Override
-	protected void onOpen(IPartialPageRequestHandler handler) {
-		handler.add(form);
-		setModelObject(name);
-		getFeedbackMessages().clear();
-	}
-
-	@Override
-	protected void onSubmit(AjaxRequestTarget target) {
-		close(target, getSubmitButton());
-	}
-
-	@Override
-	protected List<DialogButton> getButtons() {
-		return Arrays.asList(add, cancel);
-	}
-
-	@Override
-	public DialogButton getSubmitButton() {
-		return add;
-	}
-
-	@Override
-	public Form<String> getForm() {
-		return form;
-	}
-
-	@Override
-	protected void onError(AjaxRequestTarget target) {
-		target.add(feedback);
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.html
new file mode 100644
index 0000000..ef9e252
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<wicket:panel>
+	<form wicket:id="form">
+		<label style="padding-left: 20px; padding-right: 20px;" wicket:id="label"></label><input type="text" wicket:id="title"/>
+		<div wicket:id="feedback"></div>
+		<input type="submit" wicket:id="submit" class="invisible-form-component"/>
+	</form>
+</wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
new file mode 100644
index 0000000..ab4c811
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
@@ -0,0 +1,125 @@
+/*
+ * 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.common;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.openmeetings.web.app.Application;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.RequiredTextField;
+import org.apache.wicket.model.Model;
+
+import com.googlecode.wicket.jquery.core.Options;
+import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
+import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
+import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
+
+public abstract class NameDialog extends AbstractFormDialog<String> {
+	private static final long serialVersionUID = 1L;
+	private final DialogButton add;
+	private final DialogButton cancel = new DialogButton("cancel", Application.getString(219));
+	private final Form<String> form;
+	private final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
+	private final String name;
+	private RequiredTextField<String> title;
+
+	public NameDialog(String id) {
+		this(id, null);
+	}
+
+	public NameDialog(String id, String name) {
+		super(id, "", Model.of(name));
+		this.name = name;
+		add = new DialogButton("add", getAddStr());
+		form = new Form<>("form", getModel());
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
+		setTitle(Model.of(getTitleStr()));
+		form.add(new Label("label", getLabelStr())
+				, title = new RequiredTextField<>("title", getModel())
+				, feedback.setOutputMarkupId(true)
+				, new AjaxButton("submit") { //FAKE button so "submit-on-enter" works as expected
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					protected void onSubmit(AjaxRequestTarget target) {
+						NameDialog.this.onSubmit(target);
+					}
+
+					@Override
+					protected void onError(AjaxRequestTarget target) {
+						NameDialog.this.onError(target);
+					}
+				});
+		title.setLabel(Model.of(getLabelStr()));
+		add(form.setOutputMarkupId(true));
+	}
+
+	@Override
+	protected void onOpen(IPartialPageRequestHandler handler) {
+		handler.add(form);
+		setModelObject(name);
+		getFeedbackMessages().clear();
+	}
+
+	@Override
+	protected void onSubmit(AjaxRequestTarget target) {
+		close(target, getSubmitButton());
+	}
+
+	@Override
+	protected List<DialogButton> getButtons() {
+		return Arrays.asList(add, cancel);
+	}
+
+	@Override
+	public DialogButton getSubmitButton() {
+		return add;
+	}
+
+	@Override
+	public Form<String> getForm() {
+		return form;
+	}
+
+	@Override
+	protected void onError(AjaxRequestTarget target) {
+		target.add(feedback);
+	}
+
+	protected String getTitleStr() {
+		return getString("1260");
+	}
+
+	protected String getLabelStr() {
+		return getString("572");
+	}
+
+	protected String getAddStr() {
+		return Application.getString("1261");
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
index a23cbd1..dff9122 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
@@ -38,7 +38,7 @@ import org.apache.openmeetings.db.entity.file.FileExplorerItem;
 import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.db.entity.file.FileItem.Type;
 import org.apache.openmeetings.db.entity.record.Recording;
-import org.apache.openmeetings.web.common.AddFolderDialog;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.util.AjaxDownload;
@@ -91,7 +91,7 @@ public abstract class FileTreePanel extends Panel {
 		}
 	};
 	private final Form<Void> form = new Form<>("form");
-	private final AddFolderDialog addFolder;
+	private final NameDialog addFolder;
 	private final ConfirmableBorderDialog trashConfirm;
 	private ConfirmableAjaxBorder trashBorder;
 	private final Long roomId;
@@ -106,7 +106,7 @@ public abstract class FileTreePanel extends Panel {
 	});
 	private final Component upload = new WebMarkupContainer("upload");
 
-	public FileTreePanel(String id, Long roomId, AddFolderDialog addFolder, ConfirmableBorderDialog trashConfirm) {
+	public FileTreePanel(String id, Long roomId, NameDialog addFolder, ConfirmableBorderDialog trashConfirm) {
 		super(id);
 		this.roomId = roomId;
 		this.addFolder = addFolder;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
index c6aca8f..d215d71 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
@@ -26,7 +26,7 @@ import org.apache.openmeetings.db.dao.file.FileExplorerItemDao;
 import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.dto.record.RecordingContainerData;
 import org.apache.openmeetings.db.entity.file.FileItem;
-import org.apache.openmeetings.web.common.AddFolderDialog;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.common.tree.FileTreePanel;
 import org.apache.openmeetings.web.room.RoomPanel;
@@ -38,7 +38,7 @@ public class RoomFilePanel extends FileTreePanel {
 	private static final long serialVersionUID = 1L;
 	private final RoomPanel room;
 
-	public RoomFilePanel(String id, RoomPanel room, AddFolderDialog addFolder, ConfirmableBorderDialog trashConfirm) {
+	public RoomFilePanel(String id, RoomPanel room, NameDialog addFolder, ConfirmableBorderDialog trashConfirm) {
 		super(id, room.getRoom().getId(), addFolder, trashConfirm);
 		this.room = room;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index cb0e6a5..b09e688 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -34,7 +34,7 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.common.AddFolderDialog;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.room.RoomBroadcaster;
@@ -97,7 +97,7 @@ public class RoomSidebar extends Panel {
 			item.add(new RoomClientPanel("user", item, room));
 		}
 	};
-	private final AddFolderDialog addFolder = new AddFolderDialog("addFolder", Application.getString(712)) {
+	private final NameDialog addFolder = new NameDialog("addFolder", Application.getString(712)) {
 		private static final long serialVersionUID = 1L;
 
 		@Override

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
index f464953..e0eb3fa 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
@@ -61,7 +61,6 @@
 			<div wicket:message="title:62" class="ui-widget-header clickable om-icon big clear-all"></div>
 			<div wicket:message="title:1005" class="ui-widget-header clickable om-icon big clear-slide"></div>
 			<div wicket:message="title:197" class="ui-widget-header clickable om-icon big save"></div>
-<!-- save-as filename -->
 			<div wicket:message="title:70" class="ui-widget-header clickable om-icon big undo"></div>
 
 			<div wicket:message="title:72" class="ui-widget-header clickable om-icon big pointer"></div>
@@ -118,5 +117,6 @@
 			<wicket:message key="1359"/>
 		</div>
 	</div>
+	<div wicket:id="filename"></div>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index ad438ff..4f3762a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -39,6 +39,8 @@ import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.util.OmFileHelper;
+import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomResourceReference;
 import org.apache.openmeetings.web.user.record.JpgRecordingResourceReference;
@@ -79,16 +81,18 @@ public class WbPanel extends Panel {
 	private boolean readOnly = true;
 	private final Long roomId;
 	private final RoomPanel rp;
+	private long wb2save = -1;
 	private enum Action {
 		createWb
 		, removeWb
-		, activeWb
+		, activateWb
 		, setSlide
 		, createObj
 		, modifyObj
 		, deleteObj
 		, clearAll
 		, clearSlide
+		, save
 	}
 	private final AbstractDefaultAjaxBehavior wbAction = new AbstractDefaultAjaxBehavior() {
 		private static final long serialVersionUID = 1L;
@@ -106,7 +110,7 @@ public class WbPanel extends Panel {
 				JSONObject obj = sv.isEmpty() ? new JSONObject() : new JSONObject(sv.toString());
 				if (Action.createObj == a || Action.modifyObj == a) {
 					if ("pointer".equals(obj.getJSONObject("obj").getString("type"))) {
-						sendWbOthers(String.format("WbArea.%s", a.name()), obj);
+						sendWbOthers(a, obj);
 						return;
 					}
 				}
@@ -117,7 +121,7 @@ public class WbPanel extends Panel {
 						case createWb:
 						{
 							Whiteboard wb = getBean(WhiteboardCache.class).add(roomId, rp.getClient().getUser().getLanguageId());
-							sendWbAll("WbArea.add", getAddWbJson(wb.getId(), wb.getName()));
+							sendWbAll(Action.createWb, getAddWbJson(wb.getId(), wb.getName()));
 						}
 							break;
 						case removeWb:
@@ -125,16 +129,16 @@ public class WbPanel extends Panel {
 							long _id = obj.optLong("id", -1);
 							Long id = _id < 0 ? null : _id;
 							getBean(WhiteboardCache.class).remove(roomId, id);
-							sendWbAll("WbArea.remove", new JSONObject().put("id", id));
+							sendWbAll(Action.removeWb, new JSONObject().put("id", id));
 						}
 							break;
-						case activeWb:
+						case activateWb:
 						{
 							long _id = obj.optLong("id", -1);
 							if (_id > -1) {
 								Whiteboards wbs = getBean(WhiteboardCache.class).get(roomId);
 								wbs.setActiveWb(_id);
-								sendWbAll("WbArea.activate", new JSONObject().put("id", _id));
+								sendWbAll(Action.activateWb, new JSONObject().put("id", _id));
 							}
 						}
 							break;
@@ -142,7 +146,7 @@ public class WbPanel extends Panel {
 						{
 							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
 							wb.setSlide(obj.optInt("slide", 0));
-							sendWbOthers(String.format("WbArea.%s", a.name()), obj);
+							sendWbOthers(Action.setSlide, obj);
 						}
 							break;
 						case createObj:
@@ -150,7 +154,7 @@ public class WbPanel extends Panel {
 							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
 							JSONObject o = obj.getJSONObject("obj");
 							wb.put(o.getString("uid"), o);
-							sendWbOthers(String.format("WbArea.%s", a.name()), obj);
+							sendWbOthers(Action.createObj, obj);
 						}
 							break;
 						case modifyObj:
@@ -166,7 +170,7 @@ public class WbPanel extends Panel {
 									wb.put(_o.getString("uid"), _o);
 								}
 							}
-							sendWbOthers(String.format("WbArea.%s", a.name()), obj);
+							sendWbOthers(Action.modifyObj, obj);
 						}
 						case deleteObj:
 						{
@@ -175,23 +179,27 @@ public class WbPanel extends Panel {
 							for (int i = 0; i < arr.length(); ++i) {
 								wb.remove(arr.getString(i));
 							}
-							sendWbAll("WbArea.removeObj", obj);
+							sendWbAll(Action.deleteObj, obj);
 						}
 							break;
 						case clearAll:
 						{
 							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
 							wb.clear();
-							sendWbAll("WbArea.clearAll", obj);
+							sendWbAll(Action.clearAll, obj);
 						}
 							break;
 						case clearSlide:
 						{
 							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
 							wb.entrySet().removeIf(e -> e.getValue().optInt("slide", -1) == obj.getInt("slide"));
-							sendWbAll("WbArea.clearSlide", obj);
+							sendWbAll(Action.clearSlide, obj);
 						}
 							break;
+						case save:
+							wb2save = obj.getLong("wbId");
+							fileName.open(target);
+							break;
 					}
 				}
 			} catch (Exception e) {
@@ -199,6 +207,30 @@ public class WbPanel extends Panel {
 			}
 		}
 	};
+	private final NameDialog fileName = new NameDialog("filename") {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		protected void onSubmit(AjaxRequestTarget target) {
+			Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(wb2save);
+			wb.toJson();
+		}
+
+		@Override
+		protected String getTitleStr() {
+			return getString("199");
+		}
+
+		@Override
+		protected String getLabelStr() {
+			return getString("200");
+		}
+
+		@Override
+		protected String getAddStr() {
+			return Application.getString("203");
+		}
+	};
 
 	public WbPanel(String id, RoomPanel rp) {
 		super(id);
@@ -217,7 +249,7 @@ public class WbPanel extends Panel {
 					item.add(append("class", cls), append("data-mode", cls)
 							, new AttributeAppender("data-image", item.getModelObject()).setSeparator(""));
 				}
-			});
+			}, fileName);
 			add(wbAction);
 		}
 	}
@@ -242,25 +274,25 @@ public class WbPanel extends Panel {
 			}
 			sb.append("WbArea.load(").append(getObjWbJson(entry.getKey(), arr).toString()).append(");");
 		}
-		sb.append("WbArea.activate({id: ").append(wbs.getActiveWb()).append("});");
+		sb.append("WbArea.activateWb({id: ").append(wbs.getActiveWb()).append("});");
 		response.render(OnDomReadyHeaderItem.forScript(sb));
 	}
 
-	private void sendWbAll(CharSequence meth, JSONObject obj) {
+	private void sendWbAll(Action meth, JSONObject obj) {
 		sendWb(meth, obj, null);
 	}
 
-	private void sendWbOthers(CharSequence meth, JSONObject obj) {
+	private void sendWbOthers(Action meth, JSONObject obj) {
 		sendWb(meth, obj, c -> !rp.getClient().getUid().equals(c.getUid()));
 	}
 
-	private void sendWb(CharSequence meth, JSONObject obj, Predicate<Client> check) {
+	private void sendWb(Action meth, JSONObject obj, Predicate<Client> check) {
 		WebSocketHelper.sendRoom(
 				roomId
 				, new JSONObject()
 						.put("type", "wb")
 				, check
-				, (o, c) -> o.put("func", String.format("%s(%s);", meth, obj.toString())).toString()
+				, (o, c) -> o.put("func", String.format("WbArea.%s(%s);", meth.name(), obj.toString())).toString()
 			);
 	}
 
@@ -391,6 +423,9 @@ public class WbPanel extends Panel {
 					;
 			wb.put(wuid, file);
 			final String ruid = wbs.getUid();
+			if (clean) {
+				sendWbAll(Action.clearAll, new JSONObject().put("wbId", wb.getId()));
+			}
 			WebSocketHelper.sendRoom(
 					roomId
 					, new JSONObject().put("type", "wb")

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
index f875a24..c9d71b0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
@@ -1,8 +1,8 @@
 /* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */
  /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
-/* version 1.7.8 */
+
 /* Licensed MIT https://github.com/kangax/fabric.js/blob/master/LICENSE */
-var fabric = fabric || { version: "1.7.8" };
+var fabric = fabric || { version: "1.7.9" };
 if (typeof exports !== 'undefined') {
   exports.fabric = fabric;
 }
@@ -3804,8 +3804,10 @@ if (typeof console !== 'undefined') {
    * @param {Function} callback Callback to call when parsing is finished;
    * It's being passed an array of elements (parsed from a document).
    * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
+   * @param {Object} [parsingOptions] options for parsing document
+   * @param {String} [parsingOptions.crossOrigin] crossOrigin settings
    */
-  fabric.parseSVGDocument = function(doc, callback, reviver) {
+  fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {
     if (!doc) {
       return;
     }
@@ -3815,7 +3817,7 @@ if (typeof console !== 'undefined') {
     var svgUid =  fabric.Object.__uid++,
         options = applyViewboxTransform(doc),
         descendants = fabric.util.toArray(doc.getElementsByTagName('*'));
-
+    options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;
     options.svgUid = svgUid;
 
     if (descendants.length === 0 && fabric.isLikelyNode) {
@@ -3847,7 +3849,7 @@ if (typeof console !== 'undefined') {
       if (callback) {
         callback(instances, options);
       }
-    }, clone(options), reviver);
+    }, clone(options), reviver, parsingOptions);
   };
 
   var reFontDeclaration = new RegExp(
@@ -3999,8 +4001,8 @@ if (typeof console !== 'undefined') {
      * @param {Object} [options] Options object
      * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
      */
-    parseElements: function(elements, callback, options, reviver) {
-      new fabric.ElementsParser(elements, callback, options, reviver).parse();
+    parseElements: function(elements, callback, options, reviver, parsingOptions) {
+      new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();
     },
 
     /**
@@ -4126,8 +4128,10 @@ if (typeof console !== 'undefined') {
      * @param {String} url
      * @param {Function} callback
      * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
+     * @param {Object} [options] Object containing options for parsing
+     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
      */
-    loadSVGFromURL: function(url, callback, reviver) {
+    loadSVGFromURL: function(url, callback, reviver, options) {
 
       url = url.replace(/^\n\s*/, '').trim();
       new fabric.util.request(url, {
@@ -4148,9 +4152,9 @@ if (typeof console !== 'undefined') {
           callback && callback(null);
         }
 
-        fabric.parseSVGDocument(xml.documentElement, function (results, options) {
-          callback && callback(results, options);
-        }, reviver);
+        fabric.parseSVGDocument(xml.documentElement, function (results, _options) {
+          callback && callback(results, _options);
+        }, reviver, options);
       }
     },
 
@@ -4160,8 +4164,10 @@ if (typeof console !== 'undefined') {
      * @param {String} string
      * @param {Function} callback
      * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
+     * @param {Object} [options] Object containing options for parsing
+     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
      */
-    loadSVGFromString: function(string, callback, reviver) {
+    loadSVGFromString: function(string, callback, reviver, options) {
       string = string.trim();
       var doc;
       if (typeof DOMParser !== 'undefined') {
@@ -4177,21 +4183,22 @@ if (typeof console !== 'undefined') {
         doc.loadXML(string.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, ''));
       }
 
-      fabric.parseSVGDocument(doc.documentElement, function (results, options) {
-        callback(results, options);
-      }, reviver);
+      fabric.parseSVGDocument(doc.documentElement, function (results, _options) {
+        callback(results, _options);
+      }, reviver, options);
     }
   });
 
 })(typeof exports !== 'undefined' ? exports : this);
 
 
-fabric.ElementsParser = function(elements, callback, options, reviver) {
+fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {
   this.elements = elements;
   this.callback = callback;
   this.options = options;
   this.reviver = reviver;
   this.svgUid = (options && options.svgUid) || 0;
+  this.parsingOptions = parsingOptions;
 };
 
 fabric.ElementsParser.prototype.parse = function() {
@@ -19223,7 +19230,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
    * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}
    */
   fabric.Image.ATTRIBUTE_NAMES =
-    fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href'.split(' '));
+    fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));
 
   /**
    * Returns {@link fabric.Image} instance from an SVG element
@@ -24210,7 +24217,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
       }
 
       this.isEditing = true;
-
+      this.selected = true;
       this.initHiddenTextarea(e);
       this.hiddenTextarea.focus();
       this._updateTextarea();
@@ -24595,7 +24602,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
           }
         }
       }
-      var newStyle = style || currentLineStyles[charIndex - 1];
+      var newStyle = style || clone(currentLineStyles[charIndex - 1]);
       newStyle && (this.styles[lineIndex][charIndex] = newStyle);
       this._forceClearCache = true;
     },
@@ -24631,8 +24638,14 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
      * @param {Number} offset Can be -1 or +1
      */
     shiftLineStyles: function(lineIndex, offset) {
-      // shift all line styles by 1 upward
+      // shift all line styles by 1 upward or downward
       var clonedStyles = clone(this.styles);
+      for (var line in clonedStyles) {
+        var numericLine = parseInt(line, 10);
+        if (numericLine <= lineIndex) {
+          delete clonedStyles[numericLine];
+        }
+      }
       for (var line in this.styles) {
         var numericLine = parseInt(line, 10);
         if (numericLine > lineIndex) {
@@ -24847,7 +24860,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
         return;
       }
       var pointer = this.canvas.getPointer(options.e);
-
       this.__mousedownX = pointer.x;
       this.__mousedownY = pointer.y;
       this.__isMousedown = true;
@@ -25004,8 +25016,8 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
     this.hiddenTextarea = fabric.document.createElement('textarea');
     this.hiddenTextarea.setAttribute('autocapitalize', 'off');
     var style = this._calcTextareaPosition();
-    this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + '; left: ' + style.left + ';'
-                                        + ' opacity: 0; width: 0px; height: 0px; z-index: -999;';
+    this.hiddenTextarea.style.cssText = 'white-space: nowrap; position: absolute; top: ' + style.top +
+      '; left: ' + style.left + '; opacity: 0; width: 1px; height: 1px; z-index: -999;';
     fabric.document.body.appendChild(this.hiddenTextarea);
 
     fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));


[35/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1630] room counters are fixed

Posted by so...@apache.org.
[OPENMEETINGS-1630] room counters are fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/11235945
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/11235945
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/11235945

Branch: refs/heads/master
Commit: 1123594551871c32565e1529b8f914787b78af4c
Parents: 1b9cde0
Author: Maxim Solodovnik <so...@apache.org>
Authored: Tue Apr 18 17:51:44 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Tue Apr 18 17:51:44 2017 +0000

----------------------------------------------------------------------
 .../db/dto/basic/ServiceResult.java             |  5 +-
 .../openmeetings/db/dto/room/RoomCountBean.java | 53 ----------------
 .../openmeetings/db/dto/room/RoomCountDTO.java  | 66 ++++++++++++++++++++
 .../openmeetings/webservice/FileWebService.java |  3 +-
 .../webservice/GroupWebService.java             | 11 ++--
 .../openmeetings/webservice/RoomWebService.java | 17 ++---
 .../openmeetings/webservice/UserWebService.java | 34 +++++-----
 .../webservice/cluster/UserService.java         | 34 +++++-----
 8 files changed, 121 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/basic/ServiceResult.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/basic/ServiceResult.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/basic/ServiceResult.java
index 9212ca8..4393b05 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/basic/ServiceResult.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/basic/ServiceResult.java
@@ -29,6 +29,7 @@ import javax.xml.bind.annotation.XmlType;
 @XmlAccessorType(XmlAccessType.FIELD)
 public class ServiceResult implements Serializable {
 	private static final long serialVersionUID = 1L;
+	public static ServiceResult NO_PERMISSION = new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
 	private long code;
 	private String message;
 	private String type;
@@ -39,7 +40,7 @@ public class ServiceResult implements Serializable {
 	}
 
 	public ServiceResult() {}
-	
+
 	public ServiceResult(long code, String message, String type) {
 		super();
 		this.code = code;
@@ -53,7 +54,7 @@ public class ServiceResult implements Serializable {
 		this.message = message;
 		this.type = type.name();
 	}
-	
+
 	public long getCode() {
 		return code;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountBean.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountBean.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountBean.java
deleted file mode 100644
index b612e70..0000000
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountBean.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.db.dto.room;
-
-public class RoomCountBean {
-	private Long roomId;
-	private String roomName;
-	private int roomCount;
-	private long maxUser;
-	
-	public RoomCountBean() {}
-	
-	public Long getRoomId() {
-		return roomId;
-	}
-	public void setRoomId(Long roomId) {
-		this.roomId = roomId;
-	}
-	public String getRoomName() {
-		return roomName;
-	}
-	public void setRoomName(String roomName) {
-		this.roomName = roomName;
-	}
-	public int getRoomCount() {
-		return roomCount;
-	}
-	public void setRoomCount(int roomCount) {
-		this.roomCount = roomCount;
-	}
-	public long getMaxUser() {
-		return maxUser;
-	}
-	public void setMaxUser(long maxUser) {
-		this.maxUser = maxUser;
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountDTO.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountDTO.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountDTO.java
new file mode 100644
index 0000000..3a6c168
--- /dev/null
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomCountDTO.java
@@ -0,0 +1,66 @@
+/*
+ * 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.db.dto.room;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RoomCountDTO {
+	private Long roomId;
+	private String roomName;
+	private int roomCount;
+	private long maxUser;
+
+	public RoomCountDTO() {}
+
+	public Long getRoomId() {
+		return roomId;
+	}
+
+	public void setRoomId(Long roomId) {
+		this.roomId = roomId;
+	}
+
+	public String getRoomName() {
+		return roomName;
+	}
+
+	public void setRoomName(String roomName) {
+		this.roomName = roomName;
+	}
+
+	public int getRoomCount() {
+		return roomCount;
+	}
+
+	public void setRoomCount(int roomCount) {
+		this.roomCount = roomCount;
+	}
+
+	public long getMaxUser() {
+		return maxUser;
+	}
+
+	public void setMaxUser(long maxUser) {
+		this.maxUser = maxUser;
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/FileWebService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/FileWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/FileWebService.java
index ea70478..d4e8326 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/FileWebService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/FileWebService.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.webservice;
 
+import static org.apache.openmeetings.db.dto.basic.ServiceResult.NO_PERMISSION;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.webservice.Constants.TNS;
 
@@ -111,7 +112,7 @@ public class FileWebService {
 				fileDao.delete(f);
 				return new ServiceResult(id, "Deleted", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception e) {
 			log.error("[delete] ", e);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/GroupWebService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/GroupWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/GroupWebService.java
index a18f223..87a6ab6 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/GroupWebService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/GroupWebService.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.webservice;
 
+import static org.apache.openmeetings.db.dto.basic.ServiceResult.NO_PERMISSION;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.webservice.Constants.TNS;
 
@@ -106,7 +107,7 @@ public class GroupWebService {
 			return new ServiceResult(groupDao.update(o, userId).getId(), "Success", Type.SUCCESS);
 		} else {
 			log.error("Could not create group");
-			return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+			return NO_PERMISSION;
 		}
 	}
 
@@ -161,7 +162,7 @@ public class GroupWebService {
 				}
 				return new ServiceResult(userid, "Success", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("addUser", err);
@@ -205,7 +206,7 @@ public class GroupWebService {
 				}
 				return new ServiceResult(userid, "Success", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("addUser", err);
@@ -253,7 +254,7 @@ public class GroupWebService {
 				}
 				return new ServiceResult(0L, "Not added", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("[addRoom]", err);
@@ -333,7 +334,7 @@ public class GroupWebService {
 
 				return new ServiceResult(id, "Deleted", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("deleteUserById", err);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
index 98676be..adcfce6 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
@@ -39,18 +39,18 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.cxf.feature.Features;
+import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.room.IInvitationManager;
 import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.IUserManager;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.dto.basic.ServiceResult;
 import org.apache.openmeetings.db.dto.basic.ServiceResult.Type;
 import org.apache.openmeetings.db.dto.room.InvitationDTO;
-import org.apache.openmeetings.db.dto.room.RoomCountBean;
+import org.apache.openmeetings.db.dto.room.RoomCountDTO;
 import org.apache.openmeetings.db.dto.room.RoomDTO;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Invitation.MessageType;
@@ -58,8 +58,10 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
+import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.webservice.error.ServiceException;
+import org.apache.wicket.Application;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -88,8 +90,6 @@ public class RoomWebService {
 	@Autowired
 	private IInvitationManager invitationManager;
 	@Autowired
-	private ISessionManager sessionManager;
-	@Autowired
 	private RoomDao roomDao;
 
 	/**
@@ -420,19 +420,20 @@ public class RoomWebService {
 	@WebMethod
 	@GET
 	@Path("/counters")
-	public List<RoomCountBean> counters(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @QueryParam("id") List<Long> ids) throws ServiceException {
-		List<RoomCountBean> roomBeans = new ArrayList<>();
+	public List<RoomCountDTO> counters(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @QueryParam("id") List<Long> ids) throws ServiceException {
+		List<RoomCountDTO> roomBeans = new ArrayList<>();
 		try {
 			Sessiondata sd = sessionDao.check(sid);
 			if (AuthLevelUtil.hasWebServiceLevel(userDao.getRights(sd.getUserId()))) {
+				IApplication app = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
 				List<Room> rooms = roomDao.get(ids);
 
 				for (Room room : rooms) {
-					RoomCountBean rCountBean = new RoomCountBean();
+					RoomCountDTO rCountBean = new RoomCountDTO();
 					rCountBean.setRoomId(room.getId());
 					rCountBean.setRoomName(room.getName());
 					rCountBean.setMaxUser(room.getNumberOfPartizipants());
-					rCountBean.setRoomCount(sessionManager.getClientListByRoom(room.getId()).size());
+					rCountBean.setRoomCount(app.getOmRoomClients(room.getId()).size());
 
 					roomBeans.add(rCountBean);
 				}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
index 30834e7..0ff9f7f 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.webservice;
 
+import static org.apache.openmeetings.db.dto.basic.ServiceResult.NO_PERMISSION;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.webservice.Constants.TNS;
 import static org.apache.openmeetings.webservice.Constants.USER_SERVICE_NAME;
@@ -41,7 +42,7 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.cxf.feature.Features;
-import org.apache.openmeetings.core.session.SessionManager;
+import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.server.SOAPLoginDao;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
@@ -59,20 +60,22 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
 import org.apache.openmeetings.util.OmException;
+import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.webservice.cluster.UserService;
 import org.apache.openmeetings.webservice.error.ServiceException;
+import org.apache.wicket.Application;
 import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
- * 
+ *
  * The Service contains methods to login and create hash to directly enter
  * conference rooms, recordings or the application in general
- * 
+ *
  * @author sebawagner
- * 
+ *
  */
 @WebService(serviceName = USER_SERVICE_NAME, targetNamespace = TNS, portName = USER_SERVICE_PORT_NAME)
 @Features(features = "org.apache.cxf.feature.LoggingFeature")
@@ -90,8 +93,6 @@ public class UserWebService implements UserService {
 	private UserDao userDao;
 	@Autowired
 	private SessiondataDao sessionDao;
-	@Autowired
-	private SessionManager sessionManager;
 
 	/* (non-Javadoc)
 	 * @see org.apache.openmeetings.webservice.cluster.UserService#login(java.lang.String, java.lang.String)
@@ -107,7 +108,7 @@ public class UserWebService implements UserService {
 			if (u == null) {
 				return new ServiceResult(-1L, "Login failed", Type.ERROR);
 			}
-			
+
 			Sessiondata sd = sessionDao.create(u.getId(), u.getLanguageId());
 			log.debug("Login user SID : " + sd.getSessionId());
 			return new ServiceResult(u.getId(), sd.getSessionId(), Type.SUCCESS);
@@ -207,7 +208,7 @@ public class UserWebService implements UserService {
 	}
 
 	//FIXME no update
-	
+
 	/* (non-Javadoc)
 	 * @see org.apache.openmeetings.webservice.cluster.UserService#delete(java.lang.String, long)
 	 */
@@ -223,7 +224,7 @@ public class UserWebService implements UserService {
 
 				return new ServiceResult(id, "Deleted", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("deleteUserById", err);
@@ -253,7 +254,7 @@ public class UserWebService implements UserService {
 
 				return new ServiceResult(user.getId(), "Deleted", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("deleteUserByExternalUserIdAndType", err);
@@ -305,7 +306,7 @@ public class UserWebService implements UserService {
 					return new ServiceResult(0, hash, Type.SUCCESS);
 				}
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("getRoomHash", err);
@@ -326,10 +327,10 @@ public class UserWebService implements UserService {
 			Sessiondata sd = sessionDao.check(sid);
 			if (AuthLevelUtil.hasWebServiceLevel(userDao.getRights(sd.getUserId()))) {
 				Boolean success = userManagement.kickUserByPublicSID(sid, publicSID);
-	
+
 				return new ServiceResult(Boolean.TRUE.equals(success) ? 1L : 0L, Boolean.TRUE.equals(success) ? "deleted" : "not deleted", Type.SUCCESS);
 			} else {
-				return new ServiceResult(-26L, "Insufficient permissions", Type.ERROR);
+				return NO_PERMISSION;
 			}
 		} catch (Exception err) {
 			log.error("[kick]", err);
@@ -344,11 +345,12 @@ public class UserWebService implements UserService {
 	@WebMethod
 	@GET
 	@Path("/count/{roomid}")
-	public int count(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId) {
+	public ServiceResult count(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId) {
 		Sessiondata sd = sessionDao.check(sid);
 		if (AuthLevelUtil.hasUserLevel(userDao.getRights(sd.getUserId()))) {
-			return sessionManager.getClientListByRoom(roomId).size();
+			IApplication app = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
+			return new ServiceResult(app.getOmRoomClients(roomId).size(), "count", Type.SUCCESS);
 		}
-		return -1;
+		return NO_PERMISSION;
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/11235945/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/cluster/UserService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/cluster/UserService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/cluster/UserService.java
index daf9328..6ccba83 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/cluster/UserService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/cluster/UserService.java
@@ -45,33 +45,33 @@ public interface UserService {
 	/**
 	 * @param user - login or email of Openmeetings user with admin or SOAP-rights
 	 * @param pass - password
-	 *            
+	 *
 	 * @return - {@link ServiceResult} with error code or SID and userId
 	 */
 	ServiceResult login(@WebParam(name="user") @QueryParam("user") String user, @WebParam(name="pass") @QueryParam("pass") String pass);
 
 	/**
 	 * Lists all users in the system!
-	 * 
+	 *
 	 * @param sid
 	 *            The SID from getSession
-	 *            
+	 *
 	 * @return - list of users
 	 * @throws ServiceException
 	 */
 	List<UserDTO> get(@WebParam(name="sid") @QueryParam("sid") String sid) throws ServiceException;
-	
+
 	/**
 	 * Adds a new User like through the Frontend, but also does activates the
 	 * Account To do SSO see the methods to create a hash and use those ones!
-	 * 
+	 *
 	 * @param sid
 	 *            The SID from getSession
 	 * @param user
 	 *            user object
 	 * @param confirm
 	 *            whatever or not to send email, leave empty for auto-send
-	 *            
+	 *
 	 * @return - id of the user added or error code
 	 * @throws ServiceException
 	 */
@@ -82,30 +82,30 @@ public interface UserService {
 			) throws ServiceException;
 
 	/**
-	 * 
+	 *
 	 * Delete a certain user by its id
-	 * 
+	 *
 	 * @param sid
 	 *            The SID from getSession
 	 * @param id
 	 *            the openmeetings user id
-	 *            
+	 *
 	 * @return - id of the user deleted, error code otherwise
 	 * @throws ServiceException
 	 */
 	ServiceResult delete(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) throws ServiceException;
 
 	/**
-	 * 
+	 *
 	 * Delete a certain user by its external user id
-	 * 
+	 *
 	 * @param sid
 	 *            The SID from getSession
 	 * @param externalId
 	 *            externalUserId
 	 * @param externalType
 	 *            externalUserId
-	 *            
+	 *
 	 * @return - id of user deleted, or error code
 	 * @throws ServiceException
 	 */
@@ -119,14 +119,14 @@ public interface UserService {
 	 * Description: sets the SessionObject for a certain SID, after setting this
 	 * Session-Object you can use the SID + a RoomId to enter any Room. ...
 	 * Session-Hashs are deleted 15 minutes after the creation if not used.
-	 * 
+	 *
 	 * @param sid
 	 *            The SID from getSession
 	 * @param user
 	 *            user details to set
 	 * @param options
 	 *            room options to set
-	 *            
+	 *
 	 * @return - secure hash or error code
 	 * @throws ServiceException
 	 */
@@ -138,7 +138,7 @@ public interface UserService {
 
 	/**
 	 * Kick a user by its public SID
-	 * 
+	 *
 	 * @param sid
 	 *            The SID from getSession
 	 * @param publicSID
@@ -151,10 +151,10 @@ public interface UserService {
 	/**
 	 * Returns the count of users currently in the Room with given id
 	 * No admin rights are necessary for this call
-	 * 
+	 *
 	 * @param sid The SID from UserService.getSession
 	 * @param roomId id of the room to get users
 	 * @return number of users as int
 	 */
-	int count(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId);
+	ServiceResult count(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId);
 }


[41/50] [abbrv] openmeetings git commit: no jira: WS connection closed event works as expected in IE

Posted by so...@apache.org.
no jira: WS connection closed event works as expected in IE


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/876e0882
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/876e0882
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/876e0882

Branch: refs/heads/master
Commit: 876e0882e42ec1143bdb3321be1b4a6f7dcb3285
Parents: 1bd42d1
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 19 12:03:43 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 19 12:03:43 2017 +0000

----------------------------------------------------------------------
 .../src/main/java/org/apache/openmeetings/web/room/room.js         | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/876e0882/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index c85190e..a828a44 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -187,10 +187,12 @@ function roomLoad() {
 		}
 	});
 	Wicket.Event.subscribe("/websocket/closed", roomClosed);
+	Wicket.Event.subscribe("/websocket/error", roomClosed);
 }
 function roomUnload() {
 	$(window).off('resize.openmeetings');
 	Wicket.Event.unsubscribe("/websocket/closed", roomClosed);
+	Wicket.Event.unsubscribe("/websocket/error", roomClosed);
 	if (!!WbArea) {
 		WbArea.destroy();
 	}


[31/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] screen-sharing is displayed in room

Posted by so...@apache.org.
[OPENMEETINGS-551] screen-sharing is displayed in room


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/e7bab5bc
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/e7bab5bc
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/e7bab5bc

Branch: refs/heads/master
Commit: e7bab5bc4e3cf788090135045d948566472c33c9
Parents: c79c121
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sat Apr 15 16:49:12 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sat Apr 15 16:49:12 2017 +0000

----------------------------------------------------------------------
 LICENSE                                         |   41 +-
 .../core/data/conference/RoomManager.java       |   13 -
 .../openmeetings/core/remote/MobileService.java |    5 +-
 .../core/remote/RecordingService.java           |    1 -
 .../core/remote/ScopeApplicationAdapter.java    | 1262 +++++++++++++
 .../openmeetings/core/remote/UserService.java   |    1 -
 .../remote/red5/ScopeApplicationAdapter.java    | 1750 ------------------
 .../org/apache/openmeetings/IApplication.java   |    1 +
 .../apache/openmeetings/screenshare/Core.java   |   99 +-
 .../openmeetings/screenshare/IScreenShare.java  |    2 +-
 .../src/main/jnlp/templates/template.jnlp       |    3 +-
 .../openmeetings/service/user/UserManager.java  |    2 +-
 .../openmeetings/util/message/RoomMessage.java  |    2 +
 .../openmeetings/web/app/Application.java       |    7 +-
 .../openmeetings/web/common/MainPanel.java      |    2 +-
 .../openmeetings/web/room/RoomBroadcaster.java  |    2 +-
 .../apache/openmeetings/web/room/RoomPanel.java |   21 +
 .../apache/openmeetings/web/room/SwfPanel.java  |   10 +-
 .../openmeetings/web/room/VideoSettings.java    |   20 +-
 .../web/room/menu/StartSharingButton.java       |   86 +-
 .../org/apache/openmeetings/web/room/room.js    |   26 +-
 .../web/room/sidebar/RoomSidebar.java           |    2 +-
 .../WEB-INF/classes/applicationContext.xml      |    2 +-
 23 files changed, 1410 insertions(+), 1950 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index a022b5a..0907aad 100644
--- a/LICENSE
+++ b/LICENSE
@@ -498,10 +498,10 @@ The GlassFish code released under the CDDL shall be governed by the laws of the
 
 For SLF4J:
 
-lib/jcl-over-slf4j-1.7.22.jar
-lib/jul-to-slf4j-1.7.22.jar
-lib/log4j-over-slf4j-1.7.22.jar
-lib/slf4j-api-1.7.22.jar
+lib/jcl-over-slf4j-*.jar
+lib/jul-to-slf4j-*.jar
+lib/log4j-over-slf4j-*.jar
+lib/slf4j-api-*.jar
 
 Copyright (c) 2004-2008 QOS.ch
  All rights reserved.
@@ -1468,8 +1468,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 For the components:
 
-lib/logback-classic-1.1.7.jar
-lib/logback-core-1.1.7.jar
+lib/logback-classic-*.jar
+lib/logback-core-*.jar
 plugins/ecj-4.5.1.jar
 
 Eclipse Public License - v 1.0
@@ -2114,35 +2114,6 @@ As a special exception, the copyright holders of this library give you permissio
 
 =======================================================================================
 
-MIT X11 License
-https://raw.githubusercontent.com/Mahoney/sysout-over-slf4j/master/LICENSE.txt
-
-For lib/sysout-over-slf4j-1.0.2.jar
-
- * Copyright (c) 2009-2012 Robert Elliot
- * All rights reserved.
- * 
- * Permission is hereby granted, free  of charge, to any person obtaining
- * a  copy  of this  software  and  associated  documentation files  (the
- * "Software"), to  deal in  the Software without  restriction, including
- * without limitation  the rights to  use, copy, modify,  merge, publish,
- * distribute,  sublicense, and/or sell  copies of  the Software,  and to
- * permit persons to whom the Software  is furnished to do so, subject to
- * the following conditions:
- * 
- * The  above  copyright  notice  and  this permission  notice  shall  be
- * included in all copies or substantial portions of the Software.
- * 
- * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
- * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
- * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- =======================================================================================
-
  Mozilla Public License 1.1 (MPL 1.1)
  http://www.mozilla.org/MPL/MPL-1.1.html
  

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/conference/RoomManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/conference/RoomManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/conference/RoomManager.java
index 05c3172..05f5b16 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/conference/RoomManager.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/conference/RoomManager.java
@@ -32,7 +32,6 @@ import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
 
 import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.dao.room.SipDao;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dto.basic.SearchResult;
 import org.apache.openmeetings.db.entity.room.Room;
@@ -58,8 +57,6 @@ public class RoomManager {
 	private ISessionManager sessionManager;
 	@Autowired
 	private RoomDao roomDao;
-	@Autowired
-	private SipDao sipDao;
 
 	public SearchResult<Room> getRooms(int start, int max, String orderby, boolean asc, String search) {
 		try {
@@ -294,16 +291,6 @@ public class RoomManager {
 	// ---------------------------------------------------------------------------------------------
 
 	/**
-	 * Returns number of SIP conference participants
-	 * @param roomId id of room
-	 * @return number of participants
-	 */
-	public Integer getSipConferenceMembersNumber(Long roomId) {
-		Room r = roomDao.get(roomId);
-		return r == null || r.getConfno() == null ? null : sipDao.countUsers(r.getConfno());
-	}
-
-	/**
 	 * get List of RoomGroup by group and roomtype
 	 *
 	 * @param groupId

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
index e2976c4..be56543 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
@@ -18,7 +18,7 @@
  */
 package org.apache.openmeetings.core.remote;
 
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.nextBroadCastId;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.nextBroadCastId;
 import static org.apache.openmeetings.db.util.LocaleHelper.getCountryName;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_GROUP_ID;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FRONTEND_REGISTER_KEY;
@@ -39,8 +39,7 @@ import java.util.TimeZone;
 import java.util.UUID;
 
 import org.apache.commons.lang3.time.FastDateFormat;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.MessageSender;
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter.MessageSender;
 import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ChatDao;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
index eae5bc0..5e2fe7f 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
@@ -29,7 +29,6 @@ import org.apache.openmeetings.core.converter.BaseConverter;
 import org.apache.openmeetings.core.data.record.converter.InterviewConverterTask;
 import org.apache.openmeetings.core.data.record.converter.RecordingConverterTask;
 import org.apache.openmeetings.core.data.record.listener.StreamListener;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
new file mode 100644
index 0000000..52f256d
--- /dev/null
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
@@ -0,0 +1,1262 @@
+/*
+ * 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.core.remote;
+
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE_PROXY;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_VIDEO_CODEC;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.openmeetings.IApplication;
+import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
+import org.apache.openmeetings.core.util.WebSocketHelper;
+import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
+import org.apache.openmeetings.db.dao.label.LabelDao;
+import org.apache.openmeetings.db.dao.log.ConferenceLogDao;
+import org.apache.openmeetings.db.dao.record.RecordingDao;
+import org.apache.openmeetings.db.dao.room.RoomDao;
+import org.apache.openmeetings.db.dao.room.SipDao;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
+import org.apache.openmeetings.db.dao.server.ServerDao;
+import org.apache.openmeetings.db.dao.server.SessiondataDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.log.ConferenceLog;
+import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.server.Server;
+import org.apache.openmeetings.db.entity.server.Sessiondata;
+import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.util.CalendarPatterns;
+import org.apache.openmeetings.util.InitializationContainer;
+import org.apache.openmeetings.util.OmFileHelper;
+import org.apache.openmeetings.util.OpenmeetingsVariables;
+import org.apache.openmeetings.util.Version;
+import org.apache.openmeetings.util.message.RoomMessage;
+import org.apache.openmeetings.util.message.TextRoomMessage;
+import org.apache.wicket.Application;
+import org.apache.wicket.util.string.StringValue;
+import org.apache.wicket.util.string.Strings;
+import org.red5.logging.Red5LoggerFactory;
+import org.red5.server.adapter.MultiThreadedApplicationAdapter;
+import org.red5.server.api.IClient;
+import org.red5.server.api.IConnection;
+import org.red5.server.api.Red5;
+import org.red5.server.api.scope.IScope;
+import org.red5.server.api.service.IPendingServiceCall;
+import org.red5.server.api.service.IPendingServiceCallback;
+import org.red5.server.api.service.IServiceCapableConnection;
+import org.red5.server.api.stream.IBroadcastStream;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.github.openjson.JSONObject;
+
+public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter implements IPendingServiceCallback {
+	private static final Logger log = Red5LoggerFactory.getLogger(ScopeApplicationAdapter.class, webAppRootKey);
+	private static final String SECURITY_CODE_PARAM = "securityCode";
+	private static final String WIDTH_PARAM = "width";
+	private static final String HEIGHT_PARAM = "height";
+	public static final String FLASH_SECURE = "secure";
+	public static final String FLASH_NATIVE_SSL = "native";
+	public static final String FLASH_PORT = "rtmpPort";
+	public static final String FLASH_SSL_PORT = "rtmpsPort";
+	public static final String FLASH_VIDEO_CODEC = "videoCodec";
+	public static final String FLASH_FPS = "fps";
+	private static AtomicLong broadCastCounter = new AtomicLong(0);
+	private JSONObject flashSettings;
+
+	@Autowired
+	private ISessionManager sessionManager;
+	@Autowired
+	private RecordingService recordingService;
+	@Autowired
+	private ConfigurationDao cfgDao;
+	@Autowired
+	private SessiondataDao sessiondataDao;
+	@Autowired
+	private ConferenceLogDao conferenceLogDao;
+	@Autowired
+	private UserDao userDao;
+	@Autowired
+	private RoomDao roomDao;
+	@Autowired
+	private SipDao sipDao;
+	@Autowired
+	private RecordingDao recordingDao;
+	@Autowired
+	private ServerDao serverDao;
+
+	@Override
+	public void resultReceived(IPendingServiceCall arg0) {
+		if (log.isTraceEnabled()) {
+			log.trace("resultReceived:: {}", arg0);
+		}
+	}
+
+	@Override
+	public boolean appStart(IScope scope) {
+		try {
+			OmFileHelper.setOmHome(scope.getResource("/").getFile());
+			LabelDao.initLanguageMap();
+
+			log.debug("webAppPath : " + OmFileHelper.getOmHome());
+
+			// Only load this Class one time Initially this value might by empty, because the DB is empty yet
+			cfgDao.getCryptKey();
+
+			// init your handler here
+			Properties props = new Properties();
+			try (InputStream is = new FileInputStream(new File(new File(OmFileHelper.getRootDir(), "conf"), "red5.properties"))) {
+				props.load(is);
+			}
+			flashSettings = new JSONObject()
+					.put(FLASH_SECURE, "yes".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE, String.class, "no")))
+					.put(FLASH_NATIVE_SSL, "best".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE_PROXY, String.class, "none")))
+					.put(FLASH_PORT, props.getProperty("rtmp.port"))
+					.put(FLASH_SSL_PORT, props.getProperty("rtmps.port"))
+					.put(FLASH_VIDEO_CODEC, cfgDao.getConfValue(CONFIG_FLASH_VIDEO_CODEC, String.class, "h263"))
+					.put(FLASH_FPS, cfgDao.getConfValue(OpenmeetingsVariables.CONFIG_FLASH_VIDEO_FPS, Integer.class, "30"))
+					;
+
+			for (String scopeName : scope.getScopeNames()) {
+				log.debug("scopeName :: " + scopeName);
+			}
+
+			InitializationContainer.initComplete = true;
+			Version.logOMStarted();
+			recordingDao.resetProcessingStatus(); //we are starting so all processing recordings are now errors
+			sessionManager.clearCache(); // 'sticky' clients should be cleaned up from DB
+		} catch (Exception err) {
+			log.error("[appStart]", err);
+		}
+		return true;
+	}
+
+	@SuppressWarnings("unchecked")
+	private static Map<String, Object> getConnParams(Object[] params) {
+		if (params != null && params.length > 0) {
+			return (Map<String, Object>)params[0];
+		}
+		return new HashMap<>();
+	}
+
+	@Override
+	public boolean roomConnect(IConnection conn, Object[] params) {
+		log.debug("roomConnect : ");
+
+		IServiceCapableConnection service = (IServiceCapableConnection) conn;
+		String streamId = conn.getClient().getId();
+
+		log.debug("### Client connected to OpenMeetings, register Client StreamId: " + streamId + " scope " + conn.getScope().getName());
+
+		// Set StreamId in Client
+		service.invoke("setId", new Object[] { streamId }, this);
+
+		Map<String, Object> map = conn.getConnectParams();
+		String swfURL = map.containsKey("swfUrl") ? (String)map.get("swfUrl") : "";
+		String tcUrl = map.containsKey("tcUrl") ? (String)map.get("tcUrl") : "";
+		Map<String, Object> connParams = getConnParams(params);
+		String uid = (String)connParams.get("uid");
+		if ("noclient".equals(uid)) {
+			return true;
+		}
+		String securityCode = (String)connParams.get(SECURITY_CODE_PARAM);
+		String parentSid = (String)map.get("parentSid");
+		if (parentSid == null) {
+			parentSid = (String)connParams.get("parentSid");
+		}
+		StringValue scn = StringValue.valueOf(conn.getScope().getName());
+		long roomId = scn.toLong(Long.MIN_VALUE);
+		Client rcm = new Client();
+		IApplication iapp = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
+		if (!Strings.isEmpty(securityCode)) {
+			//this is for external applications like ffmpeg [OPENMEETINGS-1574]
+			if (roomId < 0) {
+				log.warn("Trying to enter invalid scope using security code, client is rejected:: " + roomId);
+				return rejectClient();
+			}
+			String _uid = null;
+			for (org.apache.openmeetings.db.entity.basic.Client wcl : iapp.getOmRoomClients(roomId)) {
+				if (wcl.getSid().equals(securityCode)) {
+					_uid = wcl.getUid();
+					break;
+				}
+			}
+			if (_uid == null) {
+				log.warn("Client is not found by security id, client is rejected");
+				return rejectClient();
+			}
+			Client parent = sessionManager.getClientByPublicSID(_uid, null);
+			if (parent == null || !parent.getScope().equals(scn.toString())) {
+				log.warn("Security code is invalid, client is rejected");
+				return rejectClient();
+			}
+			rcm.setUsername(parent.getUsername());
+			rcm.setFirstname(parent.getFirstname());
+			rcm.setLastname(parent.getLastname());
+			rcm.setUserId(parent.getUserId());
+			rcm.setPublicSID(UUID.randomUUID().toString());
+			rcm.setSecurityCode(_uid);
+			Number width = (Number)connParams.get(WIDTH_PARAM);
+			Number height = (Number)connParams.get(HEIGHT_PARAM);
+			if (width != null && height != null) {
+				rcm.setVWidth(width.intValue());
+				rcm.setVHeight(height.intValue());
+			}
+		}
+		if (Strings.isEmpty(uid) && Strings.isEmpty(securityCode) && Strings.isEmpty(parentSid)) {
+			log.warn("No UIDs are provided, client is rejected");
+			return rejectClient();
+		}
+
+		if (map.containsKey("screenClient")) {
+			org.apache.openmeetings.db.entity.basic.Client parent = iapp.getOmClient(uid);
+			if (parent == null) {
+				log.warn("Bad parent for screen-sharing client, client is rejected");
+				return rejectClient();
+			}
+			SessionVariablesUtil.setIsScreenClient(conn.getClient());
+			rcm.setUserId(parent.getUserId());
+			rcm.setScreenClient(true);
+			rcm.setPublicSID(UUID.randomUUID().toString());
+			rcm.setStreamPublishName(uid);
+		}
+		rcm.setStreamid(conn.getClient().getId());
+		rcm.setScope(scn.toString());
+		boolean notHibernate = !"hibernate".equals(scn.toString());
+		if (Long.MIN_VALUE != roomId) {
+			rcm.setRoomId(roomId);
+		} else if (notHibernate) {
+			log.warn("Bad room specified, client is rejected");
+			return rejectClient();
+		}
+		if (connParams.containsKey("mobileClient")) {
+			Sessiondata sd = sessiondataDao.check(parentSid);
+			if (sd.getUserId() == null && notHibernate) {
+				log.warn("Attempt of unauthorized room enter, client is rejected");
+				return rejectClient();
+			}
+			rcm.setMobile(true);
+			rcm.setUserId(sd.getUserId());
+			if (rcm.getUserId() != null) {
+				User u = userDao.get(rcm.getUserId());
+				if (u == null) {
+					log.error("Attempt of unauthorized room enter: USER not found, client is rejected");
+					return rejectClient();
+				}
+				rcm.setUsername(u.getLogin());
+				rcm.setFirstname(u.getFirstname());
+				rcm.setLastname(u.getLastname());
+				rcm.setEmail(u.getAddress() == null ? null : u.getAddress().getEmail());
+			}
+			rcm.setSecurityCode(sd.getSessionId());
+			rcm.setPublicSID(UUID.randomUUID().toString());
+		}
+		rcm.setUserport(conn.getRemotePort());
+		rcm.setUserip(conn.getRemoteAddress());
+		rcm.setSwfurl(swfURL);
+		rcm.setTcUrl(tcUrl);
+		if (!Strings.isEmpty(uid)) {
+			rcm.setPublicSID(uid);
+		}
+		rcm = sessionManager.add(iapp.updateClient(rcm, false), null);
+		if (rcm == null) {
+			log.warn("Failed to create Client on room connect");
+			return false;
+		}
+
+		SessionVariablesUtil.initClient(conn.getClient(), rcm.getPublicSID());
+		//TODO add similar code for other connections, merge with above block
+		if (map.containsKey("screenClient")) {
+			//TODO add check for room rights
+			User u = null;
+			Long userId = rcm.getUserId();
+			SessionVariablesUtil.setUserId(conn.getClient(), userId);
+			if (userId != null) {
+				long _uid = userId.longValue();
+				u = userDao.get(_uid < 0 ? -_uid : _uid);
+			}
+			if (u != null) {
+				rcm.setUsername(u.getLogin());
+				rcm.setFirstname(u.getFirstname());
+				rcm.setLastname(u.getLastname());
+			}
+			log.debug("publishName :: " + rcm.getStreamPublishName());
+			sessionManager.updateClientByStreamId(streamId, rcm, false, null);
+		}
+
+		// Log the User
+		conferenceLogDao.add(ConferenceLog.Type.clientConnect,
+				rcm.getUserId(), streamId, null, rcm.getUserip(),
+				rcm.getScope());
+		return true;
+	}
+
+	public Map<String, String> screenSharerAction(Map<String, Object> map) {
+		Map<String, String> returnMap = new HashMap<>();
+		try {
+			log.debug("-----------  screenSharerAction ENTER");
+			IConnection current = Red5.getConnectionLocal();
+
+			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+
+			if (client != null) {
+				boolean changed = false;
+				if (Boolean.parseBoolean("" + map.get("stopStreaming")) && client.isStartStreaming()) {
+					changed = true;
+					client.setStartStreaming(false);
+					//Send message to all users
+					sendMessageToCurrentScope("stopScreenSharingMessage", client, false);
+					WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
+
+					returnMap.put("result", "stopSharingOnly");
+				}
+				if (Boolean.parseBoolean("" + map.get("stopRecording")) && client.getIsRecording()) {
+					changed = true;
+					client.setStartRecording(false);
+					client.setIsRecording(false);
+
+					returnMap.put("result", "stopRecordingOnly");
+
+					recordingService.stopRecordAndSave(current.getScope(), client, null);
+				}
+				if (Boolean.parseBoolean("" + map.get("stopPublishing")) && client.isScreenPublishStarted()) {
+					changed = true;
+					client.setScreenPublishStarted(false);
+					returnMap.put("result", "stopPublishingOnly");
+
+					//Send message to all users
+					sendMessageToCurrentScope("stopPublishingMessage", client, false);
+				}
+
+				if (changed) {
+					sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
+
+					if (!client.isStartStreaming() && !client.isStartRecording() && !client.isStreamPublishStarted()) {
+						returnMap.put("result", "stopAll");
+					}
+				}
+			}
+			log.debug("-----------  screenSharerAction, return: " + returnMap);
+		} catch (Exception err) {
+			log.error("[screenSharerAction]", err);
+		}
+		return returnMap;
+	}
+
+	/**
+	 *
+	 * @param map
+	 * @return returns key,value Map with multiple return values or null in case of exception
+	 *
+	 */
+	public Map<String, Object> setConnectionAsSharingClient(Map<String, Object> map) {
+		try {
+			log.debug("-----------  setConnectionAsSharingClient");
+			IConnection current = Red5.getConnectionLocal();
+
+			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+
+			if (client != null) {
+				boolean startRecording = Boolean.parseBoolean("" + map.get("startRecording"));
+				boolean startStreaming = Boolean.parseBoolean("" + map.get("startStreaming"));
+				boolean startPublishing = Boolean.parseBoolean("" + map.get("startPublishing")) && (0 == sessionManager.getPublishingCount(client.getRoomId()));
+
+				boolean alreadyStreaming = client.isStartStreaming();
+				if (startStreaming) {
+					client.setStartStreaming(true);
+				}
+				boolean alreadyRecording = client.isStartRecording();
+				if (startRecording) {
+					client.setStartRecording(true);
+				}
+				if (startPublishing) {
+					client.setStreamPublishStarted(true);
+				}
+
+				client.setVX(Double.valueOf("" + map.get("screenX")).intValue());
+				client.setVY(Double.valueOf("" + map.get("screenY")).intValue());
+				client.setVWidth(Double.valueOf("" + map.get("screenWidth")).intValue());
+				client.setVHeight(Double.valueOf("" + map.get("screenHeight")).intValue());
+				client.setStreamPublishName("" + map.get("publishName"));
+				sessionManager.updateClientByStreamId(current.getClient().getId(), client, false, null);
+
+				Map<String, Object> returnMap = new HashMap<>();
+				returnMap.put("alreadyPublished", false);
+
+				// if is already started screen sharing, then there is no need to start it again
+				if (client.isScreenPublishStarted()) {
+					returnMap.put("alreadyPublished", true);
+				}
+
+				log.debug("screen x,y,width,height {},{},{},{}", client.getVX(), client.getVY(), client.getVWidth(), client.getVHeight());
+
+				if (startStreaming) {
+					if (!alreadyStreaming) {
+						returnMap.put("modus", "startStreaming");
+
+						log.debug("start streamPublishStart Is Screen Sharing ");
+
+						//Send message to all users
+						sendMessageToCurrentScope("newScreenSharing", client, false);
+						WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStarted, client.getStreamPublishName()));
+					} else {
+						log.warn("Streaming is already started for the client id=" + client.getId() + ". Second request is ignored.");
+					}
+				}
+				if (startRecording) {
+					if (!alreadyRecording) {
+						returnMap.put("modus", "startRecording");
+
+						String recordingName = "Recording " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
+
+						recordingService.recordMeetingStream(current, client, recordingName, "", false);
+					} else {
+						log.warn("Recording is already started for the client id=" + client.getId() + ". Second request is ignored.");
+					}
+				}
+				if (startPublishing) {
+					sendMessageToCurrentScope("startedPublishing", new Object[]{client, "rtmp://" + map.get("publishingHost") + ":1935/"
+							+ map.get("publishingApp") + "/" + map.get("publishingId")}, false, true);
+					returnMap.put("modus", "startPublishing");
+				}
+				return returnMap;
+			} else {
+				log.error("[setConnectionAsSharingClient] Could not find Screen Sharing Client " + current.getClient().getId());
+			}
+		} catch (Exception err) {
+			log.error("[setConnectionAsSharingClient]", err);
+		}
+		return null;
+	}
+
+	/**
+	 * Logic must be before roomDisconnect cause otherwise you cannot throw a
+	 * message to each one
+	 *
+	 */
+	@Override
+	public void roomLeave(IClient client, IScope room) {
+		try {
+			log.debug("[roomLeave] {} {} {} {}", client.getId(), room.getClients().size(), room.getContextPath(), room.getName());
+
+			Client rcl = sessionManager.getClientByStreamId(client.getId(), null);
+
+			// The Room Client can be null if the Client left the room by using
+			// logicalRoomLeave
+			if (rcl != null) {
+				log.debug("currentClient IS NOT NULL");
+				roomLeaveByScope(rcl, room);
+			}
+		} catch (Exception err) {
+			log.error("[roomLeave]", err);
+		}
+	}
+
+	public void roomLeaveByScope(String uid, Long roomId) {
+		Client rcl = sessionManager.getClientByPublicSID(uid, null);
+		IScope scope = getRoomScope("" + roomId);
+		log.debug("[roomLeaveByScope] {} {} {} {}", uid, roomId, rcl, scope);
+		if (rcl != null && scope != null) {
+			roomLeaveByScope(rcl, scope);
+		}
+	}
+
+	/**
+	 * Removes the Client from the List, stops recording, adds the Room-Leave
+	 * event to running recordings, clear Polls and removes Client from any list
+	 *
+	 * This function is kind of private/protected as the client won't be able
+	 * to call it with proper values.
+	 *
+	 * @param client
+	 * @param scope
+	 */
+	public void roomLeaveByScope(Client client, IScope scope) {
+		try {
+			log.debug("[roomLeaveByScope] currentClient " + client);
+			if (client.isScreenClient() && client.isStartStreaming()) {
+				//TODO check others/find better way
+				WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
+			}
+
+			log.debug("removing Username " + client.getUsername() + " "
+					+ client.getConnectedSince() + " streamid: "
+					+ client.getStreamid());
+
+			// stop and save any recordings
+			if (client.getIsRecording()) {
+				log.debug("*** roomLeave Current Client is Recording - stop that");
+				if (client.getInterviewPodId() != null) {
+					//interview, TODO need better check
+					_stopInterviewRecording(client, scope);
+				} else {
+					recordingService.stopRecordAndSave(scope, client, null);
+
+					// set to true and overwrite the default one cause otherwise no
+					// notification is send
+					client.setIsRecording(true);
+				}
+			}
+			recordingService.stopRecordingShowForClient(scope, client);
+
+			// Notify all clients of the same currentScope (room) with domain
+			// and room except the current disconnected cause it could throw an exception
+			log.debug("currentScope " + scope);
+
+			new MessageSender(scope, "roomDisconnect", client, this) {
+				@Override
+				public boolean filter(IConnection conn) {
+					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+					if (rcl == null) {
+						return true;
+					}
+					boolean isScreen = rcl.isScreenClient();
+					if (isScreen && client.getPublicSID().equals(rcl.getStreamPublishName())) {
+						//going to terminate screen sharing started by this client
+						((IServiceCapableConnection) conn).invoke("stopStream", new Object[] { }, callback);
+					}
+					return isScreen;
+				}
+			}.start();
+
+			if (client.isMobile()) {
+				IApplication app = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
+				app.exit(client.getPublicSID());
+			}
+			sessionManager.removeClient(client.getStreamid(), null);
+		} catch (Exception err) {
+			log.error("[roomLeaveByScope]", err);
+		}
+	}
+
+	/**
+	 * This method handles the Event after a stream has been added all connected
+	 * Clients in the same room will get a notification
+	 *
+	 */
+	/* (non-Javadoc)
+	 * @see org.red5.server.adapter.MultiThreadedApplicationAdapter#streamPublishStart(org.red5.server.api.stream.IBroadcastStream)
+	 */
+	@Override
+	public void streamPublishStart(IBroadcastStream stream) {
+		try {
+			log.debug("-----------  streamPublishStart");
+			IConnection current = Red5.getConnectionLocal();
+			final String streamid = current.getClient().getId();
+			final Client c = sessionManager.getClientByStreamId(streamid, null);
+
+			//We make a second object the has the reference to the object
+			//that we will use to send to all participents
+			Client clientObjectSendToSync = c;
+
+			// Notify all the clients that the stream had been started
+			log.debug("start streamPublishStart broadcast start: " + stream.getPublishedName() + " CONN " + current);
+
+			// In case its a screen sharing we start a new Video for that
+			if (c.isScreenClient()) {
+				c.setScreenPublishStarted(true);
+				sessionManager.updateClientByStreamId(streamid, c, false, null);
+			}
+			if (!c.isMobile() && !Strings.isEmpty(c.getSecurityCode())) {
+				c.setBroadCastID(Long.parseLong(stream.getPublishedName()));
+				c.setAvsettings("av");
+				c.setIsBroadcasting(true);
+				if (c.getVWidth() == 0 || c.getVHeight() == 0) {
+					c.setVWidth(320);
+					c.setVHeight(240);
+				}
+				sessionManager.updateClientByStreamId(streamid, c, false, null);
+			}
+
+			log.debug("newStream SEND: " + c);
+
+			// Notify all users of the same Scope
+			// We need to iterate through the streams to catch if anybody is recording
+			new MessageSender(current, "newStream", clientObjectSendToSync, this) {
+				@Override
+				public boolean filter(IConnection conn) {
+					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+
+					if (rcl == null) {
+						log.debug("RCL IS NULL newStream SEND");
+						return true;
+					}
+
+					log.debug("check send to "+rcl);
+
+					if (Strings.isEmpty(rcl.getPublicSID())) {
+						log.debug("publicSID IS NULL newStream SEND");
+						return true;
+					}
+					if (rcl.getIsRecording()) {
+						log.debug("RCL getIsRecording newStream SEND");
+						recordingService.addRecordingByStreamId(current, c, rcl.getRecordingId());
+					}
+					if (rcl.isScreenClient()) {
+						log.debug("RCL getIsScreenClient newStream SEND");
+						return true;
+					}
+
+					if (rcl.getPublicSID().equals(c.getPublicSID())) {
+						log.debug("RCL publicSID is equal newStream SEND");
+						return true;
+					}
+					log.debug("RCL SEND is equal newStream SEND "+rcl.getPublicSID()+" || "+rcl.getUserport());
+					return false;
+				}
+			}.start();
+			JSONObject obj = new JSONObject().put("uid", c.getPublicSID());
+			if (c.isScreenClient()) {
+				obj.put("screenShare", true)
+						.put("uid", c.getStreamPublishName())
+						.put("broadcastId", stream.getPublishedName())
+						.put("suid", c.getPublicSID())
+						.put("width", c.getVWidth())
+						.put("height", c.getVHeight());
+			}
+			WebSocketHelper.sendRoom(new TextRoomMessage(c.getRoomId(), c.getUserId(), RoomMessage.Type.newStream, obj.toString()));
+		} catch (Exception err) {
+			log.error("[streamPublishStart]", err);
+		}
+	}
+
+	/**
+	 * This method handles the Event after a stream has been removed all
+	 * connected Clients in the same room will get a notification
+	 *
+	 */
+	/* (non-Javadoc)
+	 * @see org.red5.server.adapter.MultiThreadedApplicationAdapter#streamBroadcastClose(org.red5.server.api.stream.IBroadcastStream)
+	 */
+	@Override
+	public void streamBroadcastClose(IBroadcastStream stream) {
+		// Notify all the clients that the stream had been closed
+		log.debug("start streamBroadcastClose broadcast close: " + stream.getPublishedName());
+		try {
+			IConnection current = Red5.getConnectionLocal();
+			String streamId = current.getClient().getId();
+			Client rcl = sessionManager.getClientByStreamId(streamId, null);
+
+			if (rcl == null) {
+
+				// In case the client has already left(kicked) this message
+				// might be thrown later then the RoomLeave
+				// event and the currentClient is already gone
+				// The second Use-Case where the currentClient is maybe null is
+				// if we remove the client because its a Zombie/Ghost
+
+				return;
+
+			}
+			// Notify all the clients that the stream had been started
+			log.debug("streamBroadcastClose : " + rcl + " " + rcl.getStreamid());
+			// this close stream event, stop the recording of this stream
+			if (rcl.getIsRecording()) {
+				log.debug("***  +++++++ ######## sendClientBroadcastNotifications Any Client is Recording - stop that");
+				recordingService.stopRecordingShowForClient(current.getScope(), rcl);
+			}
+			if (stream.getPublishedName().equals("" + rcl.getBroadCastID())) {
+				rcl.setBroadCastID(-1);
+				rcl.setIsBroadcasting(false);
+				rcl.setAvsettings("n");
+			}
+			sessionManager.updateClientByStreamId(streamId, rcl, false, null);
+			// Notify all clients of the same scope (room)
+			sendMessageToCurrentScope("closeStream", rcl, rcl.isMobile());
+			if (rcl.isScreenClient()) {
+				WebSocketHelper.sendRoom(new TextRoomMessage(rcl.getRoomId(), rcl.getUserId(), RoomMessage.Type.closeStream, rcl.getPublicSID()));
+			}
+		} catch (Exception e) {
+			log.error("[streamBroadcastClose]", e);
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	public void setNewCursorPosition(Object item) {
+		try {
+			IConnection current = Red5.getConnectionLocal();
+			Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+
+			@SuppressWarnings("rawtypes")
+			Map cursor = (Map) item;
+			cursor.put("streamPublishName", c.getStreamPublishName());
+
+			sendMessageToCurrentScope("newRed5ScreenCursor", cursor, true, false);
+		} catch (Exception err) {
+			log.error("[setNewCursorPosition]", err);
+		}
+	}
+
+	public long switchMicMuted(String publicSID, boolean mute) {
+		try {
+			log.debug("-----------  switchMicMuted: " + publicSID);
+
+			Client currentClient = sessionManager.getClientByPublicSID(publicSID, null);
+			if (currentClient == null) {
+				return -1L;
+			}
+
+			currentClient.setMicMuted(mute);
+			sessionManager.updateClientByStreamId(currentClient.getStreamid(), currentClient, false, null);
+
+			Map<Integer, Object> newMessage = new HashMap<>();
+			newMessage.put(0, "updateMuteStatus");
+			newMessage.put(1, currentClient);
+			sendMessageWithClient(newMessage);
+		} catch (Exception err) {
+			log.error("[switchMicMuted]", err);
+		}
+		return 0L;
+	}
+
+	public static long nextBroadCastId() {
+		return broadCastCounter.getAndIncrement();
+	}
+
+	public int sendMessage(Object newMessage) {
+		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
+		return 1;
+	}
+
+	public int sendMessageAll(Object newMessage) {
+		sendMessageToCurrentScope("sendVarsToMessage", newMessage, true);
+		return 1;
+	}
+
+	/**
+	 * wrapper method
+	 * @param newMessage
+	 */
+	public void sendMessageToMembers(List<?> newMessage) {
+		//Sync to all users of current scope
+		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
+	}
+
+	/**
+	 * General sync mechanism for all messages that are send from within the
+	 * scope of the current client, but:
+	 * <ul>
+	 * <li>optionally do not send to self (see param: sendSelf)</li>
+	 * <li>do not send to clients that are screen sharing clients</li>
+	 * <li>do not send to clients that are audio/video clients (or potentially ones)</li>
+	 * <li>do not send to connections where no RoomClient is registered</li>
+	 * </ul>
+	 *
+	 * @param remoteMethodName The method to be called
+	 * @param newMessage parameters
+	 * @param sendSelf send to the current client as well
+	 */
+	public void sendMessageToCurrentScope(String remoteMethodName, Object newMessage, boolean sendSelf) {
+		sendMessageToCurrentScope(remoteMethodName, newMessage, sendSelf, false);
+	}
+
+	public void sendMessageToCurrentScope(String scopeName, String remoteMethodName, Object newMessage, boolean sendSelf) {
+		sendMessageToCurrentScope(scopeName, remoteMethodName, newMessage, sendSelf, false);
+	}
+
+	public void sendToScope(final Long roomId, String method, Object obj) {
+		new MessageSender(getRoomScope("" + roomId), method, obj, this) {
+			@Override
+			public boolean filter(IConnection conn) {
+				Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+				return rcl == null || rcl.isScreenClient()
+						|| rcl.getRoomId() == null || !rcl.getRoomId().equals(roomId) || userDao.get(rcl.getUserId()) == null;
+			}
+		}.start();
+	}
+
+	/**
+	 * Only temporary for load test, with return argument for the client to have a result
+	 *
+	 * @param remoteMethodName
+	 * @param newMessage
+	 * @param sendSelf
+	 * @return true
+	 */
+	@Deprecated
+	public boolean loadTestSyncMessage(String remoteMethodName, Object newMessage, boolean sendSelf) {
+		sendMessageToCurrentScope(remoteMethodName, newMessage, sendSelf, false);
+		return true;
+	}
+
+	/**
+	 * General sync mechanism for all messages that are send from within the
+	 * scope of the current client, but:
+	 * <ul>
+	 * <li>optionally do not send to self (see param: sendSelf)</li>
+	 * <li>send to clients that are screen sharing clients based on parameter</li>
+	 * <li>do not send to clients that are audio/video clients (or potentially ones)</li>
+	 * <li>do not send to connections where no RoomClient is registered</li>
+	 * </ul>
+	 *
+	 * @param method The method to be called
+	 * @param msg parameters
+	 * @param sendSelf send to the current client as well
+	 * @param sendScreen send to the current client as well
+	 */
+	public void sendMessageToCurrentScope(final String method, final Object msg, final boolean sendSelf, final boolean sendScreen) {
+		IConnection conn = Red5.getConnectionLocal();
+		if (conn == null) {
+			log.warn("[sendMessageToCurrentScope] -> 'Unable to send message using NULL connection' {}, {}", method, msg);
+			return;
+		}
+		sendMessageToCurrentScope(conn.getScope().getName(), method, msg, sendSelf, sendScreen);
+	}
+
+	public void sendMessageToCurrentScope(final String scopeName, final String remoteMethodName, final Object newMessage, final boolean sendSelf, final boolean sendScreen) {
+		new MessageSender(getRoomScope(scopeName), remoteMethodName, newMessage, this) {
+			@Override
+			public boolean filter(IConnection conn) {
+				IClient client = conn.getClient();
+				return (!sendScreen && SessionVariablesUtil.isScreenClient(client))
+						|| (!sendSelf && current != null && client.getId().equals(current.getClient().getId()));
+			}
+		}.start();
+	}
+
+	public static abstract class MessageSender extends Thread {
+		final IScope scope;
+		final IConnection current;
+		final String method;
+		final Object msg;
+		final IPendingServiceCallback callback;
+
+		public MessageSender(final String remoteMethodName, final Object newMessage, IPendingServiceCallback callback) {
+			this((IScope)null, remoteMethodName, newMessage, callback);
+		}
+
+		public MessageSender(IScope _scope, String method, Object msg, IPendingServiceCallback callback) {
+			this(Red5.getConnectionLocal(), _scope, method, msg, callback);
+		}
+
+		public MessageSender(IConnection current, String method, Object msg, IPendingServiceCallback callback) {
+			this(current, null, method, msg, callback);
+		}
+
+		public MessageSender(IConnection current, IScope _scope, String method, Object msg, IPendingServiceCallback callback) {
+			this.current = current;
+			scope = _scope == null && current != null ? current.getScope() : _scope;
+			this.method = method;
+			this.msg = msg;
+			this.callback = callback;
+		}
+
+		public abstract boolean filter(IConnection conn);
+
+		@Override
+		public void run() {
+			try {
+				if (scope == null) {
+					log.debug("[MessageSender] -> 'Unable to send message to NULL scope' {}, {}", method, msg);
+				} else {
+					if (log.isTraceEnabled()) {
+						log.trace("[MessageSender] -> 'sending message' {}, {}", method, msg);
+					}
+					// Send to all Clients of that Scope(Room)
+					int count = 0;
+					for (IConnection conn : scope.getClientConnections()) {
+						if (conn != null && conn instanceof IServiceCapableConnection) {
+							if (filter(conn)) {
+								continue;
+							}
+							((IServiceCapableConnection) conn).invoke(method, new Object[] { msg }, callback);
+							count++;
+						}
+					}
+					if (log.isTraceEnabled()) {
+						log.trace("[MessageSender] -> 'sending message to {} clients, DONE' {}", count, method);
+					}
+				}
+			} catch (Exception err) {
+				log.error(String.format("[MessageSender -> %s, %s]", method, msg), err);
+			}
+		}
+	}
+
+	/**
+	 * wrapper method
+	 * @param newMessage
+	 * @return 1 in case of success, -1 otherwise
+	 */
+	public int sendMessageWithClient(Object newMessage) {
+		try {
+			sendMessageWithClientWithSyncObject(newMessage, true);
+
+		} catch (Exception err) {
+			log.error("[sendMessageWithClient] ", err);
+			return -1;
+		}
+		return 1;
+	}
+
+	/**
+	 * wrapper method
+	 * @param newMessage
+	 * @param sync
+	 * @return 1 in case of success, -1 otherwise
+	 */
+	public int sendMessageWithClientWithSyncObject(Object newMessage, boolean sync) {
+		try {
+			IConnection current = Red5.getConnectionLocal();
+			Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+
+			Map<String, Object> hsm = new HashMap<>();
+			hsm.put("client", currentClient);
+			hsm.put("message", newMessage);
+
+			//Sync to all users of current scope
+			sendMessageToCurrentScope("sendVarsToMessageWithClient", hsm, sync);
+
+		} catch (Exception err) {
+			log.error("[sendMessageWithClient] ", err);
+			return -1;
+		}
+		return 1;
+	}
+
+	/**
+	 * Function is used to send the kick Trigger at the moment,
+	 * it sends a general message to a specific clientId
+	 *
+	 * @param newMessage
+	 * @param clientId
+	 * @return 1 in case of success, -1 otherwise
+	 */
+	public int sendMessageById(Object newMessage, String clientId, IScope scope) {
+		try {
+			log.debug("### sendMessageById ###" + clientId);
+
+			Map<String, Object> hsm = new HashMap<>();
+			hsm.put("message", newMessage);
+
+			// broadcast Message to specific user with id inside the same Scope
+			for (IConnection conn : scope.getClientConnections()) {
+				if (conn != null) {
+					if (conn instanceof IServiceCapableConnection) {
+						if (conn.getClient().getId().equals(clientId)) {
+							((IServiceCapableConnection) conn).invoke("sendVarsToMessageWithClient", new Object[] { hsm }, this);
+						}
+					}
+				}
+			}
+		} catch (Exception err) {
+			log.error("[sendMessageWithClient] ", err);
+			return -1;
+		}
+		return 1;
+	}
+
+	/**
+	 * Sends a message to a user in the same room by its clientId
+	 *
+	 * @param newMessage
+	 * @param clientId
+	 * @return 1 in case of no exceptions, -1 otherwise
+	 */
+	public int sendMessageWithClientById(Object newMessage, String clientId) {
+		try {
+			IConnection current = Red5.getConnectionLocal();
+			Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+
+			Map<String, Object> hsm = new HashMap<>();
+			hsm.put("client", currentClient);
+			hsm.put("message", newMessage);
+
+			// broadcast Message to specific user with id inside the same Scope
+			for (IConnection conn : current.getScope().getClientConnections()) {
+				if (conn.getClient().getId().equals(clientId)) {
+					((IServiceCapableConnection) conn).invoke("sendVarsToMessageWithClient", new Object[] { hsm }, this);
+				}
+			}
+		} catch (Exception err) {
+			log.error("[sendMessageWithClient] ", err);
+			return -1;
+		}
+		return 1;
+	}
+
+	/**
+	 * @deprecated this method should be reworked to use a single SQL query in
+	 *             the cache to get any client in the current room that is
+	 *             recording instead of iterating through connections!
+	 * @return true in case there is recording session, false otherwise, null if any exception happend
+	 */
+	@Deprecated
+	public boolean getInterviewRecordingStatus() {
+		try {
+			IConnection current = Red5.getConnectionLocal();
+
+			for (IConnection conn : current.getScope().getClientConnections()) {
+				if (conn != null) {
+					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+
+					if (rcl.getIsRecording()) {
+						return true;
+					}
+				}
+			}
+		} catch (Exception err) {
+			log.error("[getInterviewRecordingStatus]", err);
+		}
+		return false;
+	}
+
+	/**
+	 * @deprecated @see {@link ScopeApplicationAdapter#getInterviewRecordingStatus()}
+	 * @return - false if there were existing recording, true if recording was started successfully, null if any exception happens
+	 */
+	@Deprecated
+	public boolean startInterviewRecording() {
+		try {
+			log.debug("-----------  startInterviewRecording");
+			IConnection current = Red5.getConnectionLocal();
+
+			for (IConnection conn : current.getScope().getClientConnections()) {
+				if (conn != null) {
+					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+
+					if (rcl != null && rcl.getIsRecording()) {
+						return false;
+					}
+				}
+			}
+			Client current_rcl = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+
+			// Also set the Recording Flag to Record all Participants that enter
+			// later
+			current_rcl.setIsRecording(true);
+			sessionManager.updateClientByStreamId(current.getClient().getId(), current_rcl, false, null);
+
+			Map<String, String> interviewStatus = new HashMap<>();
+			interviewStatus.put("action", "start");
+
+			for (IConnection conn : current.getScope().getClientConnections()) {
+				if (conn != null) {
+					IClient client = conn.getClient();
+					if (SessionVariablesUtil.isScreenClient(client)) {
+						// screen sharing clients do not receive events
+						continue;
+					}
+
+					((IServiceCapableConnection) conn).invoke("interviewStatus", new Object[] { interviewStatus }, this);
+					log.debug("-- startInterviewRecording " + interviewStatus);
+				}
+			}
+			String recordingName = "Interview " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
+
+			recordingService.recordMeetingStream(current, current_rcl, recordingName, "", true);
+
+			return true;
+		} catch (Exception err) {
+			log.debug("[startInterviewRecording]", err);
+		}
+		return false;
+	}
+
+	@SuppressWarnings({ "rawtypes" })
+	public boolean sendRemoteCursorEvent(final String streamid, Map messageObj) {
+		new MessageSender("sendRemoteCursorEvent", messageObj, this) {
+
+			@Override
+			public boolean filter(IConnection conn) {
+				IClient client = conn.getClient();
+				return !SessionVariablesUtil.isScreenClient(client) || !conn.getClient().getId().equals(streamid);
+			}
+		}.start();
+		return true;
+	}
+
+	private Long checkRecordingClient(IConnection conn) {
+		Long recordingId = null;
+		if (conn != null) {
+			Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+			if (rcl != null && rcl.getIsRecording()) {
+				rcl.setIsRecording(false);
+				recordingId = rcl.getRecordingId();
+				rcl.setRecordingId(null);
+
+				// Reset the Recording Flag to Record all
+				// Participants that enter later
+				sessionManager.updateClientByStreamId(conn.getClient().getId(), rcl, false, null);
+			}
+		}
+		return recordingId;
+	}
+
+	/**
+	 * Stop the recording of the streams and send event to connected users of scope
+	 *
+	 * @return true if interview was found
+	 */
+	public boolean stopInterviewRecording() {
+		IConnection current = Red5.getConnectionLocal();
+		Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+		return _stopInterviewRecording(currentClient, current.getScope());
+	}
+
+	/**
+	 * Stop the recording of the streams and send event to connected users of scope
+	 *
+	 * @return true if interview was found
+	 */
+	private boolean _stopInterviewRecording(Client currentClient, IScope currentScope) {
+		try {
+			log.debug("-----------  stopInterviewRecording");
+			Long clientRecordingId = currentClient.getRecordingId();
+
+			for (IConnection conn : currentScope.getClientConnections()) {
+				Long recordingId = checkRecordingClient(conn);
+				if (recordingId != null) {
+					clientRecordingId = recordingId;
+				}
+			}
+			if (clientRecordingId == null) {
+				log.debug("stopInterviewRecording:: unable to find recording client");
+				return false;
+			}
+
+			recordingService.stopRecordAndSave(scope, currentClient, clientRecordingId);
+
+			Map<String, String> interviewStatus = new HashMap<>();
+			interviewStatus.put("action", "stop");
+
+			sendMessageToCurrentScope("interviewStatus", interviewStatus, true);
+			return true;
+
+		} catch (Exception err) {
+			log.debug("[stopInterviewRecording]", err);
+		}
+		return false;
+	}
+
+	public IScope getRoomScope(String room) {
+		if (Strings.isEmpty(room)) {
+			return null;
+		} else {
+			IScope globalScope = getContext().getGlobalScope();
+			IScope webAppKeyScope = globalScope.getScope(OpenmeetingsVariables.webAppRootKey);
+
+			return webAppKeyScope.getScope(room);
+		}
+	}
+
+	/*
+	 * SIP transport methods
+	 */
+
+	private List<Long> getVerifiedActiveRoomIds(Server s) {
+		List<Long> result = new ArrayList<>(sessionManager.getActiveRoomIdsByServer(s));
+		//verify
+		for (Iterator<Long> i = result.iterator(); i.hasNext();) {
+			Long id = i.next();
+			List<Client> rcs = sessionManager.getClientListByRoom(id);
+			if (rcs.size() == 0 || (rcs.size() == 1 && rcs.get(0).isSipTransport())) {
+				i.remove();
+			}
+		}
+		return result.isEmpty() ? result : roomDao.getSipRooms(result);
+	}
+
+	public List<Long> getActiveRoomIds() {
+		List<Long> result = getVerifiedActiveRoomIds(null);
+		for (Server s : serverDao.getActiveServers()) {
+			result.addAll(getVerifiedActiveRoomIds(s));
+		}
+		return result.isEmpty() ? result : roomDao.getSipRooms(result);
+	}
+
+	/**
+	 * Returns number of SIP conference participants
+	 * @param roomId id of room
+	 * @return number of participants
+	 */
+	public Integer getSipConferenceMembersNumber(Long roomId) {
+		Room r = roomDao.get(roomId);
+		return r == null || r.getConfno() == null ? null : sipDao.countUsers(r.getConfno());
+	}
+
+	private String getSipTransportLastname(Long roomId) {
+		return getSipTransportLastname(getSipConferenceMembersNumber(roomId));
+	}
+
+	private static String getSipTransportLastname(Integer c) {
+		return (c != null && c > 0) ? "(" + (c - 1) + ")" : "";
+	}
+
+	public synchronized int updateSipTransport() {
+		log.debug("-----------  updateSipTransport");
+		IConnection current = Red5.getConnectionLocal();
+		String streamid = current.getClient().getId();
+		Client client = sessionManager.getClientByStreamId(streamid, null);
+		Long roomId = client.getRoomId();
+		Integer count = getSipConferenceMembersNumber(roomId);
+		String newNumber = getSipTransportLastname(count);
+		log.debug("getSipConferenceMembersNumber: " + newNumber);
+		if (!newNumber.equals(client.getLastname())) {
+			client.setLastname(newNumber);
+			sessionManager.updateClientByStreamId(streamid, client, false, null);
+			log.debug("updateSipTransport: {}, {}, {}, {}, {}", new Object[] { client.getPublicSID(), client.getRoomId(),
+					client.getFirstname(), client.getLastname(), client.getAvsettings() });
+			sendMessageWithClient(new String[] { "personal", client.getFirstname(), client.getLastname() });
+		}
+		return count != null && count > 0 ? count - 1 : 0;
+	}
+
+	public void setSipTransport(Long roomId, String publicSID, String broadCastId) {
+		log.debug("-----------  setSipTransport");
+		IConnection current = Red5.getConnectionLocal();
+		IClient c = current.getClient();
+		String streamid = c.getId();
+		// Notify all clients of the same scope (room)
+		Client currentClient = sessionManager.getClientByStreamId(streamid, null);
+		currentClient.setSipTransport(true);
+		currentClient.setRoomId(roomId);
+		currentClient.setRoomEnter(new Date());
+		currentClient.setFirstname("SIP Transport");
+		currentClient.setLastname(getSipTransportLastname(roomId));
+		currentClient.setBroadCastID(Long.parseLong(broadCastId));
+		currentClient.setIsBroadcasting(true);
+		currentClient.setPublicSID(publicSID);
+		currentClient.setVWidth(120);
+		currentClient.setVHeight(90);
+		currentClient.setPicture_uri("phone.png");
+		sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
+		SessionVariablesUtil.initClient(c, publicSID);
+
+		sendMessageToCurrentScope("addNewUser", currentClient, false);
+	}
+
+	public JSONObject getFlashSettings() {
+		return flashSettings;
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
index 4837982..7cc741a 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
@@ -26,7 +26,6 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.openmeetings.IApplication;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.server.ServerDao;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;


[18/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] basic work on video settings

Posted by so...@apache.org.
[OPENMEETINGS-551] basic work on video settings


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/35544aaf
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/35544aaf
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/35544aaf

Branch: refs/heads/master
Commit: 35544aafcd363362ad2530e15f1bc6d464157ade
Parents: d8febfd
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sat Apr 8 10:09:46 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sat Apr 8 10:09:46 2017 +0000

----------------------------------------------------------------------
 openmeetings-flash/pom.xml                      |   2 +-
 openmeetings-flash/src/main/flex/main.mxml      |   8 +-
 .../openmeetings/web/common/NameDialog.java     |   2 +-
 .../web/common/tree/FileTreePanel.java          |   4 +-
 .../web/pages/InvitationPasswordDialog.java     |   6 +-
 .../web/pages/auth/ForgetPasswordDialog.java    |  13 +-
 .../web/pages/auth/KickMessageDialog.java       |   5 +-
 .../web/pages/auth/RegisterDialog.java          |  25 +--
 .../web/pages/auth/ResetPasswordDialog.java     |  19 +-
 .../web/pages/auth/SignInDialog.java            |   6 +-
 .../web/pages/install/InstallWizard.java        |   2 +-
 .../openmeetings/web/room/NicknameDialog.java   |   6 +-
 .../web/room/RedirectMessageDialog.java         |  25 ++-
 .../org/apache/openmeetings/web/room/room.js    |  53 +++++-
 .../web/room/sidebar/RoomSidebar.html           |  67 +++++++
 .../web/room/sidebar/icon/SettingsIcon.java     |   4 +-
 .../openmeetings/web/room/wb/WbPanel.java       | 176 +++++++++++--------
 .../org/apache/openmeetings/web/room/wb/wb.js   |  31 ++--
 .../web/user/calendar/AppointmentDialog.java    |   2 +-
 .../web/util/NonClosableDialog.java             |  39 ++++
 .../web/util/NonClosableMessageDialog.java      |  46 +++++
 openmeetings-web/src/main/webapp/css/room.css   |  37 ++++
 22 files changed, 402 insertions(+), 176 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-flash/pom.xml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/pom.xml b/openmeetings-flash/pom.xml
index ca687f7..be7f36c 100644
--- a/openmeetings-flash/pom.xml
+++ b/openmeetings-flash/pom.xml
@@ -16,7 +16,7 @@
    limitations under the License.
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>org.apache.openmeetings</groupId>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-flash/src/main/flex/main.mxml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/main.mxml b/openmeetings-flash/src/main/flex/main.mxml
index e173816..9287291 100644
--- a/openmeetings-flash/src/main/flex/main.mxml
+++ b/openmeetings-flash/src/main/flex/main.mxml
@@ -19,9 +19,9 @@
 
 -->
 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
-			   xmlns:s="library://ns.adobe.com/flex/spark"
-			   xmlns:mx="library://ns.adobe.com/flex/mx" width="570" height="900" pageTitle="Openmeetings"
-			   preinitialize="init()" fontSize="12" applicationComplete="appInit()">
+		xmlns:s="library://ns.adobe.com/flex/spark"
+		xmlns:mx="library://ns.adobe.com/flex/mx" width="570" height="900" pageTitle="Openmeetings"
+		preinitialize="init()" fontSize="12" applicationComplete="appInit()">
 	<fx:Declarations>
 		<!-- Place non-visual elements (e.g., services, value objects) here -->
 		<mx:TraceTarget/>
@@ -477,7 +477,7 @@
 					</s:Group>
 				</s:Scroller>
 				<s:Label id="timerText" height="20" width="45" x="{videoGroup.width - 60}" y="5" paddingLeft="5" paddingTop="5"
-				         visible="false" backgroundColor="0xf5f5f5" fontWeight="bold"><s:text></s:text></s:Label>
+						visible="false" backgroundColor="0xf5f5f5" fontWeight="bold"><s:text></s:text></s:Label>
 				<s:VGroup id="playGroup">
 					<s:Group>
 						<s:Graphic x="0" z="1">

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
index ab4c811..5a7992d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/NameDialog.java
@@ -40,7 +40,7 @@ public abstract class NameDialog extends AbstractFormDialog<String> {
 	private final DialogButton add;
 	private final DialogButton cancel = new DialogButton("cancel", Application.getString(219));
 	private final Form<String> form;
-	private final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
+	protected final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
 	private final String name;
 	private RequiredTextField<String> title;
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
index dff9122..37552d2 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
@@ -38,9 +38,9 @@ import org.apache.openmeetings.db.entity.file.FileExplorerItem;
 import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.db.entity.file.FileItem.Type;
 import org.apache.openmeetings.db.entity.record.Recording;
-import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
@@ -149,7 +149,7 @@ public abstract class FileTreePanel extends Panel {
 								String statement = "var $drop = $(this);";
 								statement += "$('body').append('<div id=" + dialogId + ">" + getString("713") + "</div>');";
 								statement += "$( '#" + dialogId
-										+ "' ).dialog({ title: '" + escapeEcmaScript(getString("80")) + "', dialogClass: 'no-close', buttons: [";
+										+ "' ).dialog({ title: '" + escapeEcmaScript(getString("80")) + "', classes: {'ui-dialog-titlebar': 'ui-corner-all no-close'}, buttons: [";
 								statement += "	{ text: '" + escapeEcmaScript(getString("54")) + "', click: function() { $drop.append(ui.draggable); $(this).dialog('close'); " + super.getCallbackFunctionBody(parameters) + " } },";
 								statement += "	{ text: '" + escapeEcmaScript(getString("25")) + "', click: function() { $(this).dialog('close'); } } ";
 								statement += "],";

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
index ef994a0..2dddfbb 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
@@ -26,6 +26,7 @@ import org.apache.openmeetings.util.crypt.CryptProvider;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.IUpdatable;
+import org.apache.openmeetings.web.util.NonClosableDialog;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
@@ -38,11 +39,10 @@ import org.apache.wicket.validation.ValidationError;
 
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
 import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
 
-public class InvitationPasswordDialog extends AbstractFormDialog<Invitation> {
+public class InvitationPasswordDialog extends NonClosableDialog<Invitation> {
 	private static final long serialVersionUID = 1L;
 	private final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
 	private final DialogButton check = new DialogButton("check", Application.getString(537));
@@ -87,8 +87,6 @@ public class InvitationPasswordDialog extends AbstractFormDialog<Invitation> {
 		super.onConfigure(behavior);
 		Invitation i = WebSession.get().getInvitation();
 		behavior.setOption("autoOpen", i != null && i.isPasswordProtected());
-		behavior.setOption("closeOnEscape", false);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
 		behavior.setOption("resizable", false);
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java
index e89f9f7..0767e03 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ForgetPasswordDialog.java
@@ -32,6 +32,7 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.service.mail.template.ResetPasswordTemplate;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.pages.ResetPage;
+import org.apache.openmeetings.web.util.NonClosableMessageDialog;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
@@ -48,12 +49,9 @@ import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
-import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
 import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButtons;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogIcon;
 import com.googlecode.wicket.jquery.ui.widget.dialog.MessageDialog;
 import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
 
@@ -136,17 +134,10 @@ public class ForgetPasswordDialog extends AbstractFormDialog<String> {
 				super.onDetach();
 			}
 		});
-		confirmDialog = new MessageDialog("confirmDialog", Application.getString(312), Application.getString(321), DialogButtons.OK, DialogIcon.INFO){
+		confirmDialog = new NonClosableMessageDialog("confirmDialog", Application.getString(312), Application.getString(321)){
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			public void onConfigure(JQueryBehavior behavior) {
-				super.onConfigure(behavior);
-				behavior.setOption("dialogClass", Options.asString("no-close"));
-				behavior.setOption("closeOnEscape", false);
-			}
-
-			@Override
 			public void onClose(IPartialPageRequestHandler handler, DialogButton button) {
 				s.open(handler);
 			}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
index 0bea145..b2f489f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
@@ -24,7 +24,6 @@ import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.markup.html.basic.Label;
 
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
-import com.googlecode.wicket.jquery.core.Options;
 import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
 
@@ -40,13 +39,13 @@ public class KickMessageDialog extends AbstractDialog<String> {
 		super.onInitialize();
 		add(new Label("message", getString("606")));
 	};
-	
+
 	@Override
 	public void onConfigure(JQueryBehavior behavior) {
 		super.onConfigure(behavior);
 		behavior.setOption("autoOpen", true);
 		behavior.setOption("closeOnEscape", false);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
+		behavior.setOption("classes", "{'ui-dialog-titlebar': 'ui-corner-all no-close'}");
 		behavior.setOption("resizable", false);
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
index 9306db1..b2fc869 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
@@ -39,6 +39,8 @@ import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.LanguageDropDown;
 import org.apache.openmeetings.web.util.CountryDropDown;
+import org.apache.openmeetings.web.util.NonClosableDialog;
+import org.apache.openmeetings.web.util.NonClosableMessageDialog;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
@@ -55,16 +57,12 @@ import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
-import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButtons;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogIcon;
 import com.googlecode.wicket.jquery.ui.widget.dialog.MessageDialog;
 import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
 
-public class RegisterDialog extends AbstractFormDialog<String> {
+public class RegisterDialog extends NonClosableDialog<String> {
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(RegisterDialog.class, webAppRootKey);
 	private DialogButton cancelBtn = new DialogButton("cancel", Application.getString(122));
@@ -92,18 +90,10 @@ public class RegisterDialog extends AbstractFormDialog<String> {
 		form.setOutputMarkupId(true);
 		tzDropDown.setOutputMarkupId(true);
 
-		confirmRegistration = new MessageDialog("confirmRegistration", Application.getString(235),
-				Application.getString(674), DialogButtons.OK, DialogIcon.INFO) {
+		confirmRegistration = new NonClosableMessageDialog("confirmRegistration", Application.getString(235), Application.getString(674)) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			public void onConfigure(JQueryBehavior behavior) {
-				super.onConfigure(behavior);
-				behavior.setOption("dialogClass", Options.asString("no-close"));
-				behavior.setOption("closeOnEscape", false);
-			}
-
-			@Override
 			public void onClose(IPartialPageRequestHandler handler, DialogButton button) {
 				s.open(handler);
 			}
@@ -112,13 +102,6 @@ public class RegisterDialog extends AbstractFormDialog<String> {
 		reset();
 	}
 
-	@Override
-	public void onConfigure(JQueryBehavior behavior) {
-		super.onConfigure(behavior);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
-		behavior.setOption("closeOnEscape", false);
-	}
-
 	public void setSignInDialog(SignInDialog s) {
 		this.s = s;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ResetPasswordDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ResetPasswordDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ResetPasswordDialog.java
index e0fefec..8346aa1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ResetPasswordDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/ResetPasswordDialog.java
@@ -29,6 +29,8 @@ import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.util.NonClosableDialog;
+import org.apache.openmeetings.web.util.NonClosableMessageDialog;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
@@ -39,14 +41,11 @@ import org.apache.wicket.model.Model;
 
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButtons;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogIcon;
 import com.googlecode.wicket.jquery.ui.widget.dialog.MessageDialog;
 import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
 
-public class ResetPasswordDialog extends AbstractFormDialog<String> {
+public class ResetPasswordDialog extends NonClosableDialog<String> {
 	private static final long serialVersionUID = 1L;
 	private DialogButton resetBtn = new DialogButton("reset", Application.getString(327));
 	private Form<String> form;
@@ -101,18 +100,10 @@ public class ResetPasswordDialog extends AbstractFormDialog<String> {
 			}
 
 		});
-		confirmReset = new MessageDialog("confirmReset", Application.getString(325), Application.getString(332),
-				DialogButtons.OK, DialogIcon.INFO) {
+		confirmReset = new NonClosableMessageDialog("confirmReset", Application.getString(325), Application.getString(332)) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			public void onConfigure(JQueryBehavior behavior) {
-				super.onConfigure(behavior);
-				behavior.setOption("dialogClass", Options.asString("no-close"));
-				behavior.setOption("closeOnEscape", false);
-			}
-
-			@Override
 			public void onClose(IPartialPageRequestHandler handler, DialogButton button) {
 				setResponsePage(Application.get().getSignInPageClass());
 			}
@@ -124,8 +115,6 @@ public class ResetPasswordDialog extends AbstractFormDialog<String> {
 	public void onConfigure(JQueryBehavior behavior) {
 		super.onConfigure(behavior);
 		behavior.setOption("autoOpen", true);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
-		behavior.setOption("closeOnEscape", false);
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.java
index 186a72b..4349a8f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.java
@@ -42,6 +42,7 @@ import org.apache.openmeetings.web.app.OmAuthenticationStrategy;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.OmAjaxClientInfoBehavior;
 import org.apache.openmeetings.web.pages.HashPage;
+import org.apache.openmeetings.web.util.NonClosableDialog;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.RestartResponseException;
 import org.apache.wicket.ajax.AjaxEventBehavior;
@@ -72,11 +73,10 @@ import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
 import com.googlecode.wicket.jquery.ui.effect.JQueryEffectBehavior;
 import com.googlecode.wicket.jquery.ui.form.button.Button;
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
 import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
 
-public class SignInDialog extends AbstractFormDialog<String> {
+public class SignInDialog extends NonClosableDialog<String> {
 	private static final long serialVersionUID = 1L;
 	private Form<String> form;
 	private DialogButton loginBtn = new DialogButton("login", Application.getString(112));
@@ -107,8 +107,6 @@ public class SignInDialog extends AbstractFormDialog<String> {
 	public void onConfigure(JQueryBehavior behavior) {
 		super.onConfigure(behavior);
 		behavior.setOption("autoOpen", true);
-		behavior.setOption("closeOnEscape", false);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
 		behavior.setOption("resizable", false);
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizard.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizard.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizard.java
index 7b790da..0fdf955 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizard.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizard.java
@@ -135,7 +135,7 @@ public class InstallWizard extends AbstractWizard<InstallationConfig> {
 	public void onConfigure(JQueryBehavior behavior) {
 		super.onConfigure(behavior);
 		behavior.setOption("closeOnEscape", false);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
+		behavior.setOption("classes", "{'ui-dialog-titlebar': 'ui-corner-all no-close'}");
 		behavior.setOption("resizable", false);
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java
index 094e38b..76879e5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NicknameDialog.java
@@ -27,6 +27,7 @@ import java.util.List;
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.util.NonClosableDialog;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.validation.validator.RfcCompliantEmailAddressValidator;
 import org.apache.wicket.markup.html.form.Form;
@@ -37,11 +38,10 @@ import org.apache.wicket.util.string.Strings;
 
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
 import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
 
-public class NicknameDialog extends AbstractFormDialog<User> {
+public class NicknameDialog extends NonClosableDialog<User> {
 	private static final long serialVersionUID = 1L;
 	private static final FastDateFormat TIME_DF = FastDateFormat.getInstance("HH:mm:ss");
 	private final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
@@ -72,8 +72,6 @@ public class NicknameDialog extends AbstractFormDialog<User> {
 	public void onConfigure(JQueryBehavior behavior) {
 		super.onConfigure(behavior);
 		behavior.setOption("autoOpen", isVisible(form.getModelObject()));
-		behavior.setOption("closeOnEscape", false);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
 		behavior.setOption("resizable", false);
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RedirectMessageDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RedirectMessageDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RedirectMessageDialog.java
index 9da7695..76bd5c5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RedirectMessageDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RedirectMessageDialog.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 
 import org.apache.directory.api.util.Strings;
 import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.util.NonClosableMessageDialog;
 import org.apache.wicket.Component;
 import org.apache.wicket.RestartResponseException;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -30,26 +31,24 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.request.flow.RedirectToUrlException;
 
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
-import com.googlecode.wicket.jquery.core.Options;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogIcon;
-import com.googlecode.wicket.jquery.ui.widget.dialog.MessageDialog;
 
-public class RedirectMessageDialog extends MessageDialog {
+public class RedirectMessageDialog extends NonClosableMessageDialog {
 	private static final long serialVersionUID = 1L;
 	private final String labelId;
 	private final String url;
 	private final int delay = 5;
 	private final boolean autoOpen;
-	private Component label; 
-	
+	private Component label;
+
 	public RedirectMessageDialog(String id, String labelId, boolean autoOpen, String url) {
 		super(id, Application.getString(204), "", new ArrayList<DialogButton>(), DialogIcon.ERROR);
 		this.labelId = labelId;
 		this.url = url;
 		this.autoOpen = autoOpen;
 	}
-	
+
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
@@ -75,36 +74,34 @@ public class RedirectMessageDialog extends MessageDialog {
 			handler.add(label);
 		}
 	}
-	
+
 	@Override
 	protected void onOpen(IPartialPageRequestHandler handler) {
 		super.onOpen(handler);
 		startTimer(handler);
 	}
-	
+
 	@Override
 	public void onConfigure(JQueryBehavior behavior) {
 		super.onConfigure(behavior);
 		behavior.setOption("autoOpen", autoOpen);
-		behavior.setOption("closeOnEscape", false);
-		behavior.setOption("dialogClass", Options.asString("no-close"));
 		behavior.setOption("resizable", false);
 	}
-	
+
 	@Override
 	public boolean isModal() {
 		return true;
 	}
-	
+
 	@Override
 	public boolean isDefaultCloseEventEnabled() {
 		return false;
 	}
-	
+
 	@Override
 	public void onClose(IPartialPageRequestHandler handler, DialogButton button) {
 	}
-	
+
 	@Override
 	protected Component newLabel(String id, IModel<String> model) {
 		label = super.newLabel(id, model);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index fd447d7..1fb06cc 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -17,6 +17,7 @@
  * under the License.
  */
 function initVideo(_options) {
+	return; //commented until video is implemented
 	var options = $.extend({bgcolor: "#ffffff"
 		, resolutions: JSON.stringify([{label: "4:3 (~6 KByte/sec)", width: 40, height: 30}
 			, {label: "4:3 (~12 KByte/sec)", width: 80, height: 60}
@@ -37,7 +38,7 @@ function initVideo(_options) {
 	var type = 'application/x-shockwave-flash';
 	var src = 'public/main.swf?cache' + new Date().getTime();
 	var r = $('<div class="room video">').attr("id", "video" + options.uid);
-	var o = $('<object>').attr('type', type).attr('data', src);
+	var o = $('<object>').attr('type', type).attr('data', src).attr('width', 640).attr('height', 480);
 	o.append($('<param>').attr('name', 'quality').attr('value', 'best'))
 		.append($('<param>').attr('name', 'wmode').attr('value', 'transparent'))
 		.append($('<param>').attr('name', 'allowscriptaccess').attr('value', 'sameDomain'))
@@ -104,6 +105,7 @@ function roomLoad() {
 			setRoomSizes();
 		}
 	});
+	VideoSettings.init();
 	Wicket.Event.subscribe("/websocket/closed", roomClosed);
 }
 function roomUnload() {
@@ -112,12 +114,61 @@ function roomUnload() {
 	if (!!WbArea) {
 		WbArea.destroy();
 	}
+	VideoSettings.close();
 }
 function startPrivateChat(el) {
 	Chat.addTab('chatTab-u' + el.parent().parent().data("userid"), el.parent().parent().find('.user.name').text());
 	Chat.open();
 	$('#chatMessage .wysiwyg-editor').click();
 }
+var VideoSettings = (function() {
+	var self = {}, vs, lm;
+	function _init() {
+		vs = $('#video-settings');
+		lm = vs.find('.level-meter');
+		vs.dialog({
+			classes: {
+				'ui-dialog': 'ui-corner-all video'
+			}
+			, width: 640
+			, autoOpen: false
+			, buttons: [
+				{
+					text: vs.data('btn-save')
+					, icons: {
+						primary: "ui-icon-disk"
+					}
+					, click: function() {
+						vs.dialog("close");
+					}
+				}
+				, {
+					text: vs.data('btn-cancel')
+					, click: function() {
+						vs.dialog("close");
+					}
+				}
+			]
+		});
+		lm.progressbar({ value: 0 });
+		vs.find('button').button();
+	}
+	function _open(interview) {
+		var rr = vs.find('.cam-resolution').parent('.sett-row');
+		if (interview) {
+			rr.show();
+		} else {
+			rr.hide();
+		}
+		vs.dialog('open');
+	}
+	return {
+		init: _init
+		, open: _open
+		, close: function() { vs.dialog('close'); }
+	};
+})();
+
 /***** functions required by SIP   ******/
 function sipBtnClick() {
 	var txt = $('.sip-number');

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
index a174b10..9e5b7ac 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
@@ -40,5 +40,72 @@
 	<form wicket:id="form"><div wicket:id="confirm-trash"></div></form>
 	<div wicket:id="upload"></div>
 	<div wicket:id="confirm-kick" />
+	<div id="video-settings" wicket:message="title:51, data-btn-save:144, data-btn-cancel:25" style="display:none;">
+		<div class="title"><wicket:message key="758"/></div>
+		<div class="sett-container">
+			<div class="opt-block">
+				<div class="sett-row">
+					<div><wicket:message key="52"/></div>
+					<div>
+						<select class="cam">
+							<option value="-1"><wicket:message key="159"/></option>
+						</select>
+					</div>
+				</div>
+				<div class="sett-row">
+					<div><wicket:message key="53"/></div>
+					<div>
+						<select class="mic">
+							<option value="-1"><wicket:message key="159"/></option>
+						</select>
+					</div>
+				</div>
+				<div class="sett-row">
+					<div class="clear">
+						<wicket:message key="1429"/>
+						<span class="warn ui-state-highlight" wicket:message="title:1430">
+							<span class="ui-icon ui-icon-alert"></span>
+						</span>
+					</div>
+					<div>
+						<select class="cam-resolution">
+							<option value="1" data-width="40" data-height="30">40x30 [4:3 (~6 KByte/sec)]</option>
+							<option value="2" data-width="80" data-height="60">80x60 [4:3 (~12 KByte/sec)]</option>
+							<option value="3" data-width="120" data-height="90" selected="selected">120x90 [4:3 (~20 KByte/sec)]</option>
+							<option value="4" data-width="160" data-height="120">160x120 [QQVGA 4:3 (~36 KByte/sec)]</option>
+							<option value="5" data-width="240" data-height="180">240x180 [4:3 (~40 KByte/sec)]</option>
+							<option value="6" data-width="320" data-height="240">320x240 [HVGA 4:3 (~56 KByte/sec)]</option>
+							<option value="7" data-width="480" data-height="360">480x360 [4:3  (~60 KByte/sec)]</option>
+							<option value="8" data-width="640" data-height="480">640x480 [4:3 (~68 KByte/sec)]</option>
+							<option value="9" data-width="1024" data-height="768">1024x768 [XGA 4:3]</option>
+							<option value="10" data-width="256" data-height="150">256x150 [16:9]</option>
+							<option value="11" data-width="432" data-height="240">432x240 [WQVGA 9:5]</option>
+							<option value="12" data-width="480" data-height="234">480x234 [pseudo 16:9]</option>
+							<option value="13" data-width="512" data-height="300">512x300 [16:9]</option>
+							<option value="14" data-width="640" data-height="360">640x360 [nHD 16:9]</option>
+							<option value="15" data-width="1024" data-height="600">1024x600 [16:9]</option>
+						</select>
+					</div>
+				</div>
+				<div class="sett-row">
+					<div class="align-right"><button><wicket:message key="775"/></button></div>
+				</div>
+			</div>
+			<div class="vid-block">
+				<div>
+				</div>
+				<div class="level-meter"></div>
+				<div class="sett-row">
+					<div class="align-right"><button><wicket:message key="764"/></button></div>
+				</div>
+			</div>
+		</div>
+		<div>
+			<span style="padding: 5px;">
+				<span class="ui-icon ui-icon-info"></span>
+			</span>
+			<wicket:message key="765"/>
+		</div>
+	</div>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
index 566dae5..0c9f020 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
@@ -24,7 +24,7 @@ import org.apache.openmeetings.web.room.RoomPanel;
 
 public class SettingsIcon extends ClientIcon {
 	private static final long serialVersionUID = 1L;
-	
+
 	public SettingsIcon(String id, Client client, RoomPanel room) {
 		super(id, client, room);
 		mainCssClass = "settings ";
@@ -42,6 +42,6 @@ public class SettingsIcon extends ClientIcon {
 
 	@Override
 	protected String getScript() {
-		return String.format("document.getElementById('lzapp').showAvSettings(%s);", Room.Type.interview == room.getRoom().getType());
+		return String.format("VideoSettings.open(%s);", Room.Type.interview == room.getRoom().getType());
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index 4f3762a..47e6fd4 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -18,11 +18,17 @@
  */
 package org.apache.openmeetings.web.room.wb;
 
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.wicket.AttributeModifier.append;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
 import java.util.Arrays;
 import java.util.Map.Entry;
 import java.util.UUID;
@@ -35,7 +41,9 @@ import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.dto.room.Whiteboard;
 import org.apache.openmeetings.db.dto.room.Whiteboards;
 import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.file.FileExplorerItem;
 import org.apache.openmeetings.db.entity.file.FileItem;
+import org.apache.openmeetings.db.entity.file.FileItem.Type;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.util.OmFileHelper;
@@ -63,12 +71,16 @@ import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.resource.FileSystemResourceReference;
 import org.apache.wicket.util.string.StringValue;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
 
 import com.github.openjson.JSONArray;
 import com.github.openjson.JSONObject;
+import com.github.openjson.JSONTokener;
 
 public class WbPanel extends Panel {
 	private static final long serialVersionUID = 1L;
+	private static final Logger log = Red5LoggerFactory.getLogger(WbPanel.class, webAppRootKey);
 	private static final int UPLOAD_WB_LEFT = 0;
 	private static final int UPLOAD_WB_TOP = 0;
 	private static final int DEFAULT_WIDTH = 640;
@@ -126,19 +138,19 @@ public class WbPanel extends Panel {
 							break;
 						case removeWb:
 						{
-							long _id = obj.optLong("id", -1);
+							long _id = obj.optLong("wbId", -1);
 							Long id = _id < 0 ? null : _id;
 							getBean(WhiteboardCache.class).remove(roomId, id);
-							sendWbAll(Action.removeWb, new JSONObject().put("id", id));
+							sendWbAll(Action.removeWb, obj);
 						}
 							break;
 						case activateWb:
 						{
-							long _id = obj.optLong("id", -1);
+							long _id = obj.optLong("wbId", -1);
 							if (_id > -1) {
 								Whiteboards wbs = getBean(WhiteboardCache.class).get(roomId);
 								wbs.setActiveWb(_id);
-								sendWbAll(Action.activateWb, new JSONObject().put("id", _id));
+								sendWbAll(Action.activateWb, obj);
 							}
 						}
 							break;
@@ -185,8 +197,7 @@ public class WbPanel extends Panel {
 						case clearAll:
 						{
 							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
-							wb.clear();
-							sendWbAll(Action.clearAll, obj);
+							clearAll(wb);
 						}
 							break;
 						case clearSlide:
@@ -213,7 +224,19 @@ public class WbPanel extends Panel {
 		@Override
 		protected void onSubmit(AjaxRequestTarget target) {
 			Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(wb2save);
-			wb.toJson();
+			FileExplorerItem f = new FileExplorerItem();
+			f.setType(Type.WmlFile);
+			f.setRoomId(roomId);
+			f.setHash(UUID.randomUUID().toString());
+			f.setName(getModelObject());
+			f = getBean(FileExplorerItemDao.class).update(f);
+			try (BufferedWriter writer = Files.newBufferedWriter(f.getFile().toPath())) {
+				writer.write(wb.toJson().toString(2));
+			} catch (IOException e) {
+				error("Unexpected error while saving WB: " + e.getMessage());
+				target.add(feedback);
+				log.error("Unexpected error while saving WB", e);
+			}
 		}
 
 		@Override
@@ -274,7 +297,7 @@ public class WbPanel extends Panel {
 			}
 			sb.append("WbArea.load(").append(getObjWbJson(entry.getKey(), arr).toString()).append(");");
 		}
-		sb.append("WbArea.activateWb({id: ").append(wbs.getActiveWb()).append("});");
+		sb.append("WbArea.activateWb({wbId: ").append(wbs.getActiveWb()).append("});");
 		response.render(OnDomReadyHeaderItem.forScript(sb));
 	}
 
@@ -289,23 +312,18 @@ public class WbPanel extends Panel {
 	private void sendWb(Action meth, JSONObject obj, Predicate<Client> check) {
 		WebSocketHelper.sendRoom(
 				roomId
-				, new JSONObject()
-						.put("type", "wb")
+				, new JSONObject().put("type", "wb")
 				, check
 				, (o, c) -> o.put("func", String.format("WbArea.%s(%s);", meth.name(), obj.toString())).toString()
 			);
 	}
 
 	private static JSONObject getObjWbJson(Long wbId, Object o) {
-		return new JSONObject()
-				.put("wbId", wbId)
-				.put(PARAM_OBJ, o);
+		return new JSONObject().put("wbId", wbId).put(PARAM_OBJ, o);
 	}
 
 	private static JSONObject getAddWbJson(Long id, String name) {
-		return new JSONObject()
-				.put("id", id)
-				.put("name", name);
+		return new JSONObject().put("wbId", id).put("name", name);
 	}
 
 	public boolean isReadOnly() {
@@ -327,7 +345,7 @@ public class WbPanel extends Panel {
 
 	private JSONObject addFileUrl(String ruid, JSONObject _file) {
 		try {
-		final long fid = _file.optLong("fileId", -1);
+			final long fid = _file.optLong("fileId", -1);
 			if (fid > 0) {
 				FileItem fi = FileItem.Type.Recording.name().equals(_file.optString("fileType"))
 						? getBean(RecordingDao.class).get(fid)
@@ -371,72 +389,78 @@ public class WbPanel extends Panel {
 		return file;
 	}
 
-	/*
-	 * OLD VERSION
-	 *
-	public void sendFileToWb(FileItem fi, boolean clean) {
-		if (wb.isVisible() && fi.getId() != null && FileItem.Type.Folder != fi.getType()) {
-			long activeWbId = -1;
-			if (FileItem.Type.WmlFile == fi.getType()) {
-				getBean(ConferenceLibrary.class).sendToWhiteboard(getClient().getUid(), activeWbId, fi);
-			} else {
-				String url = null;
-				PageParameters pp = new PageParameters();
-				pp.add("id", fi.getId())
-					.add("ruid", getBean(WhiteboardCache.class).get(r.getId()).getUid());
-				switch (fi.getType()) {
-					case Video:
-						pp.add("preview", true);
-						url = urlFor(new RoomResourceReference(), pp).toString();
-						break;
-					case Recording:
-						url = urlFor(new JpgRecordingResourceReference(), pp).toString();
-						break;
-					default:
-						url = urlFor(new RoomResourceReference(), pp).toString();
-						break;
-				}
-				getBean(ScopeApplicationAdapter.class).sendToWhiteboard(getClient().getUid(), activeWbId, fi, url, clean);
-			}
-		}
+	private void clearAll(Whiteboard wb) {
+		wb.clear();
+		sendWbAll(Action.clearAll, new JSONObject().put("wbId", wb.getId()));
 	}
-	 */
 
 	public void sendFileToWb(FileItem fi, boolean clean) {
-		if (isVisible() && fi.getId() != null && FileItem.Type.Folder != fi.getType()) {
-			//FIXME TODO WmlFile/Chart special handling
+		if (isVisible() && fi.getId() != null) {
 			Whiteboards wbs = getBean(WhiteboardCache.class).get(roomId);
 			String wuid = UUID.randomUUID().toString();
 			Whiteboard wb = wbs.get(wbs.getActiveWb());
-			//FIXME TODO various types
-			JSONObject file = new JSONObject()
-					.put("fileId", fi.getId())
-					.put("fileType", fi.getType().name())
-					.put("count", fi.getCount())
-					.put("type", "image")
-					.put("left", UPLOAD_WB_LEFT)
-					.put("top", UPLOAD_WB_TOP)
-					.put("width", fi.getWidth() == null ? DEFAULT_WIDTH : fi.getWidth())
-					.put("height", fi.getHeight() == null ? DEFAULT_HEIGHT : fi.getHeight())
-					.put("uid", wuid)
-					.put("slide", wb.getSlide())
-					;
-			wb.put(wuid, file);
-			final String ruid = wbs.getUid();
-			if (clean) {
-				sendWbAll(Action.clearAll, new JSONObject().put("wbId", wb.getId()));
-			}
-			WebSocketHelper.sendRoom(
-					roomId
-					, new JSONObject().put("type", "wb")
-					, null
-					, (o, c) -> {
-							return o.put("func", String.format("WbArea.%s(%s);"
-									, Action.createObj.name()
-									, getObjWbJson(wb.getId(), addFileUrl(ruid, file, fi, c)).toString())
-								).toString();
+			switch (fi.getType()) {
+				case Folder:
+					//do nothing
+					break;
+				case WmlFile:
+				{
+					File f = fi.getFile();
+					if (f.exists() && f.isFile()) {
+						try (BufferedReader br = Files.newBufferedReader(f.toPath())) {
+							JSONObject wbo = new JSONObject(new JSONTokener(br));
+							/*WebSocketHelper.sendRoom(
+									roomId
+									, new JSONObject().put("type", "wb")
+									, null
+									, (o, c) -> {
+											return o.put("func", String.format("WbArea.%s(%s);"
+													, Action.createObj.name()
+													, getObjWbJson(wb.getId(), addFileUrl(ruid, file, fi, c)).toString())
+												).toString();
+										}
+									);*/
+						} catch (IOException e) {
+							log.error("Unexpected error while loading WB", e);
 						}
-					);
+					}
+				}
+					break;
+				case PollChart:
+					break;
+				default:
+				{
+					JSONObject file = new JSONObject()
+							.put("fileId", fi.getId())
+							.put("fileType", fi.getType().name())
+							.put("count", fi.getCount())
+							.put("type", "image")
+							.put("left", UPLOAD_WB_LEFT)
+							.put("top", UPLOAD_WB_TOP)
+							.put("width", fi.getWidth() == null ? DEFAULT_WIDTH : fi.getWidth())
+							.put("height", fi.getHeight() == null ? DEFAULT_HEIGHT : fi.getHeight())
+							.put("uid", wuid)
+							.put("slide", wb.getSlide())
+							;
+					wb.put(wuid, file);
+					final String ruid = wbs.getUid();
+					if (clean) {
+						clearAll(wb);
+					}
+					WebSocketHelper.sendRoom(
+							roomId
+							, new JSONObject().put("type", "wb")
+							, null
+							, (o, c) -> {
+									return o.put("func", String.format("WbArea.%s(%s);"
+											, Action.createObj.name()
+											, getObjWbJson(wb.getId(), addFileUrl(ruid, file, fi, c)).toString())
+										).toString();
+								}
+							);
+				}
+					break;
+			}
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index d2da4dd..f580f19 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -1085,6 +1085,15 @@ var WbArea = (function() {
 		});
 		wbTabs.find(".ui-tabs-panel .scroll-container").height(wbah);
 	}
+	function _addCloseBtn(li) {
+		if (readOnly) {
+			return;
+		}
+		li.append($('#wb-tab-close').clone().attr('id', ''));
+		li.find('button').click(function() {
+			wbAction('removeWb', JSON.stringify({wbId: li.data().wbId}));
+		});
+	}
 	self.getWbTabId = function(id) {
 		return "wb-tab-" + id;
 	};
@@ -1122,10 +1131,8 @@ var WbArea = (function() {
 					scroll.scrollLeft(scroll.scrollLeft() + 30);
 				});
 				tabsNav.find('li').each(function(idx) {
-					$(this).append($('#wb-tab-close').clone().attr('id', ''));
-					$(this).find('button').click(function() {
-						wbAction('removeWb', JSON.stringify({id: obj.id}));
-					});
+					var li = $(this);
+					_addCloseBtn(li);
 				});
 				$(window).keyup(deleteHandler);
 			}
@@ -1145,7 +1152,7 @@ var WbArea = (function() {
 				return res;
 			}
 			, activate: function(e, ui) {
-				wbAction('activateWb', JSON.stringify({id: ui.newTab.data('wb-id')}));
+				wbAction('activateWb', JSON.stringify({wbId: ui.newTab.data('wb-id')}));
 			}
 		});
 		scroll = tabs.find('.scroll-container');
@@ -1162,26 +1169,28 @@ var WbArea = (function() {
 		$(window).off('keyup', deleteHandler);
 	};
 	self.create = function(obj) {
-		var tid = self.getWbTabId(obj.id)
-			, li = $('#wb-area-tab').clone().attr('id', '').data('wb-id', obj.id)
+		var tid = self.getWbTabId(obj.wbId)
+			, li = $('#wb-area-tab').clone().attr('id', '').data('wb-id', obj.wbId)
 			, wb = $('#wb-area').clone().attr('id', tid);
 		li.find('a').text(obj.name).attr('title', obj.name).attr('href', "#" + tid);
 	
 		tabs.find(".ui-tabs-nav").append(li);
 		tabs.append(wb);
 		refreshTabs();
+		_addCloseBtn(li);
 	
 		var wbo = Wb();
 		wb.data(wbo);
-		wbo.init(obj.id, tid, readOnly);
+		wbo.init(obj.wbId, tid, readOnly);
 		_resizeWbs();
 	}
 	self.createWb = function(obj) {
 		self.create(obj);
-		_activateTab(obj.id);
+		self.setReadOnly(readOnly);
+		_activateTab(obj.wbId);
 	};
 	self.activateWb = function(obj) {
-		_activateTab(obj.id);
+		_activateTab(obj.wbId);
 	}
 	self.load = function(json) {
 		self.getWb(json.wbId).load(json.obj);
@@ -1206,7 +1215,7 @@ var WbArea = (function() {
 		self.getWb(json.wbId).clearSlide(json.slide);
 	};
 	self.removeWb = function(obj) {
-		var tabId = self.getWbTabId(obj.id);
+		var tabId = self.getWbTabId(obj.wbId);
 		tabs.find('li[aria-controls="' + tabId + '"]').remove();
 		$("#" + tabId).remove();
 		refreshTabs();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
index bb7e55a..e468e36 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
@@ -129,7 +129,7 @@ public class AppointmentDialog extends AbstractFormDialog<Appointment> {
 	@Override
 	public void onConfigure(JQueryBehavior behavior) {
 		super.onConfigure(behavior);
-		behavior.setOption("dialogClass", Options.asString("appointment"));
+		behavior.setOption("classes", "{'ui-dialog': 'ui-corner-all appointment'}");
 	}
 
 	public void setModelObjectWithAjaxTarget(Appointment a, AjaxRequestTarget target) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableDialog.java
new file mode 100644
index 0000000..8f8a5ec
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableDialog.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+
+import com.googlecode.wicket.jquery.core.JQueryBehavior;
+import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
+
+public abstract class NonClosableDialog<T extends Serializable> extends AbstractFormDialog<T> {
+	private static final long serialVersionUID = 1L;
+
+	public NonClosableDialog(String id, String title) {
+		super(id, title);
+	}
+
+	@Override
+	public void onConfigure(JQueryBehavior behavior) {
+		super.onConfigure(behavior);
+		behavior.setOption("closeOnEscape", false);
+		behavior.setOption("classes", "{'ui-dialog-titlebar': 'ui-corner-all no-close'}");
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableMessageDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableMessageDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableMessageDialog.java
new file mode 100644
index 0000000..2778268
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/NonClosableMessageDialog.java
@@ -0,0 +1,46 @@
+/*
+ * 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.util;
+
+import java.util.List;
+
+import com.googlecode.wicket.jquery.core.JQueryBehavior;
+import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
+import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButtons;
+import com.googlecode.wicket.jquery.ui.widget.dialog.DialogIcon;
+import com.googlecode.wicket.jquery.ui.widget.dialog.MessageDialog;;
+
+public abstract class NonClosableMessageDialog extends MessageDialog {
+	private static final long serialVersionUID = 1L;
+
+	public NonClosableMessageDialog(String id, String title, String message) {
+		super(id, title, message, DialogButtons.OK, DialogIcon.INFO);
+	}
+
+	public NonClosableMessageDialog(String id, String title, String message, List<DialogButton> buttons, DialogIcon icon) {
+		super(id, title, message, buttons, icon);
+	}
+
+	@Override
+	public void onConfigure(JQueryBehavior behavior) {
+		super.onConfigure(behavior);
+		behavior.setOption("classes", "{'ui-dialog-titlebar': 'ui-corner-all no-close'}");
+		behavior.setOption("closeOnEscape", false);
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/35544aaf/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index cfbe13c..18f6f4c 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -356,6 +356,43 @@
 	padding: 0;
 	overflow: hidden;
 }
+.ui-dialog.video .ui-dialog-titlebar {
+	padding-left:10px
+}
+.ui-dialog.video .title {
+	font-weight: bold;
+}
+.ui-dialog.video .opt-block {
+	width: 300px;
+	display: inline-block;
+	position: absolute;
+	top: 0;
+	left: 0;
+}
+.ui-dialog.video .vid-block {
+	min-width: 300px;
+	padding-left: 305px;
+}
+.ui-dialog.video .level-meter {
+	height: 16px;
+}
+.ui-dialog.video .warn {
+	float: right;
+	margin-right: .3em;
+}
+.ui-dialog.video .level-meter .ui-progressbar-value {
+	background: greenyellow;
+}
+.ui-dialog.video .sett-container {
+	position: relative;
+	min-height: 200px;
+}
+.ui-dialog.video .sett-row {
+	padding-top: 10px;
+}
+.ui-dialog.video .sett-row select, .ui-dialog.video .level-meter {
+	width: 250px;
+}
 .input .select2-container {
 	max-height: 100px;
 	overflow-y: auto;


[03/50] [abbrv] openmeetings git commit: add dbezhetskov as developer

Posted by so...@apache.org.
add dbezhetskov as developer


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/f5476aab
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/f5476aab
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/f5476aab

Branch: refs/heads/master
Commit: f5476aab0f579fa2a01a47719ed2eca35956ccb4
Parents: aaab149
Author: Dmitry Bezhetskov <db...@apache.org>
Authored: Sat Apr 1 04:11:05 2017 +0000
Committer: Dmitry Bezhetskov <db...@apache.org>
Committed: Sat Apr 1 04:11:05 2017 +0000

----------------------------------------------------------------------
 pom.xml | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/f5476aab/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 67519ba..535d743 100644
--- a/pom.xml
+++ b/pom.xml
@@ -340,6 +340,14 @@
 			</roles>
 		</developer>
 		<developer>
+			<name>Dmitry Bezhetskov</name>
+			<organization>Unipro</organization>
+			<organizationUrl>http://unipro.ru</organizationUrl>
+			<roles>
+				<role>developer</role>
+			</roles>
+		</developer>
+		<developer>
 			<id>albus</id>
 			<name>Alvaro Bustos</name>
 			<email>zurcamos@gmail.com</email>


[23/50] [abbrv] openmeetings git commit: [OPENMEETINGS-980] cxf, selenium and postgres versions are updated

Posted by so...@apache.org.
[OPENMEETINGS-980] cxf, selenium and postgres versions are updated


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/b27ea434
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/b27ea434
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/b27ea434

Branch: refs/heads/master
Commit: b27ea434f6febf6501737c7d64f1bfbe60e7d30f
Parents: 4e2f127
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 12 05:23:09 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 12 05:23:09 2017 +0000

----------------------------------------------------------------------
 openmeetings-db/pom.xml | 45 ++++++++++++++++++++------------------------
 pom.xml                 |  4 ++--
 2 files changed, 22 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b27ea434/openmeetings-db/pom.xml
----------------------------------------------------------------------
diff --git a/openmeetings-db/pom.xml b/openmeetings-db/pom.xml
index ff9dcf5..a49cd87 100644
--- a/openmeetings-db/pom.xml
+++ b/openmeetings-db/pom.xml
@@ -16,8 +16,8 @@
    limitations under the License.
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" 
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>org.apache.openmeetings</groupId>
@@ -35,7 +35,7 @@
 		<commons-dbcp.version>2.1.1</commons-dbcp.version>
 		<commons-pool.version>1.6</commons-pool.version> <!-- required by OpenJPA for clustering -->
 		<commons-pool2.version>2.4.2</commons-pool2.version>
-		<postgresql.version>9.4.1212.jre7</postgresql.version>
+		<postgresql.version>42.0.0</postgresql.version>
 		<site.basedir>${project.parent.basedir}</site.basedir>
 	</properties>
 	<dependencies>
@@ -107,11 +107,6 @@
 			<artifactId>postgresql</artifactId>
 			<version>${postgresql.version}</version>
 		</dependency>
-		<dependency>
-			<groupId>com.tdunning</groupId>
-			<artifactId>json</artifactId>
-			<version>1.8</version> <!-- FIXME need to be removed with update to wicket-8.x -->
-		</dependency>
 	</dependencies>
 	<build>
 		<plugins>
@@ -120,27 +115,27 @@
 				<artifactId>openjpa-maven-plugin</artifactId>
 				<version>${openjpa.version}</version>
 				<configuration>
-				    <includes>**/entity/**/*.class</includes>
-				    <addDefaultConstructor>true</addDefaultConstructor>               
-				    <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
-				    <persistenceXmlFile>${project.parent.basedir}/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml</persistenceXmlFile>
+					<includes>**/entity/**/*.class</includes>
+					<addDefaultConstructor>true</addDefaultConstructor>
+					<enforcePropertyRestrictions>true</enforcePropertyRestrictions>
+					<persistenceXmlFile>${project.parent.basedir}/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml</persistenceXmlFile>
 				</configuration>
 				<executions>
-				    <execution>
-				        <id>enhancer</id>
-				        <phase>process-classes</phase>
-				        <goals>
-				            <goal>enhance</goal>
-				        </goals>
-				    </execution>
+					<execution>
+						<id>enhancer</id>
+						<phase>process-classes</phase>
+						<goals>
+							<goal>enhance</goal>
+						</goals>
+					</execution>
 				</executions>
 				<dependencies>
-				    <dependency>
-				        <groupId>org.apache.openjpa</groupId>
-				        <artifactId>openjpa</artifactId>
-				        <!-- set the version to be the same as the level in your runtime -->
-				        <version>${openjpa.version}</version>
-				    </dependency>
+					<dependency>
+						<groupId>org.apache.openjpa</groupId>
+						<artifactId>openjpa</artifactId>
+						<!-- set the version to be the same as the level in your runtime -->
+						<version>${openjpa.version}</version>
+					</dependency>
 				</dependencies>
 			</plugin>
 		</plugins>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b27ea434/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 70f13c5..255937b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,8 +49,8 @@
 		<mina.version>2.0.16</mina.version>
 		<tomcat.version>8.5.12</tomcat.version>
 		<ical4j.version>2.0.0</ical4j.version>
-		<cxf.version>3.1.9</cxf.version>
-		<selenium.version>3.0.1</selenium.version>
+		<cxf.version>3.1.11</cxf.version>
+		<selenium.version>3.3.1</selenium.version>
 		<simple-xml.version>2.7.1</simple-xml.version>
 		<jettison.version>1.3.8</jettison.version>
 		<site.basedir>${project.basedir}</site.basedir>


[27/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] basic video support is added

Posted by so...@apache.org.
[OPENMEETINGS-551] basic video support is added


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/838bfbe3
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/838bfbe3
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/838bfbe3

Branch: refs/heads/master
Commit: 838bfbe3b9987bd4c9cfadb39cb08a3b79fff66c
Parents: e227dd4
Author: Maxim Solodovnik <so...@apache.org>
Authored: Thu Apr 13 16:29:41 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Thu Apr 13 16:29:41 2017 +0000

----------------------------------------------------------------------
 .../remote/red5/ScopeApplicationAdapter.java    |   6 +-
 .../openmeetings/db/entity/basic/Client.java    |  64 +++++++++-
 openmeetings-flash/src/main/flex/main.mxml      | 122 ++++++++++++-------
 .../flex/org/apache/openmeetings/OmVideo.as     |  44 ++++---
 .../openmeetings/web/app/Application.java       |   2 +-
 .../openmeetings/web/common/MainPanel.java      |  56 +++++----
 .../apache/openmeetings/web/pages/HashPage.java |   5 +-
 .../apache/openmeetings/web/room/RoomPanel.html |   5 +
 .../apache/openmeetings/web/room/RoomPanel.java |  20 ++-
 .../openmeetings/web/room/VideoSettings.java    |   6 +-
 .../org/apache/openmeetings/web/room/room.js    |  94 ++++++++++++++
 .../apache/openmeetings/web/room/settings.js    |   7 +-
 .../web/room/sidebar/RoomSidebar.java           |  14 ++-
 .../web/util/ExtendedClientProperties.java      |  27 +++-
 openmeetings-web/src/main/webapp/css/room.css   |  19 ++-
 pom.xml                                         |   2 +-
 16 files changed, 373 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
index ab9d5ab..f0e5db7 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
@@ -201,6 +201,9 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		String tcUrl = map.containsKey("tcUrl") ? (String)map.get("tcUrl") : "";
 		Map<String, Object> connParams = getConnParams(params);
 		String uid = (String)connParams.get("uid");
+		if ("noclient".equals(uid)) {
+			return true;
+		}
 		String securityCode = (String)connParams.get(SECURITY_CODE_PARAM);
 		String parentSid = (String)map.get("parentSid");
 		if (parentSid == null) {
@@ -249,9 +252,6 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			log.warn("No UIDs are provided, client is rejected");
 			return rejectClient();
 		}
-		if ("networktest".equals(uid)) {
-			return true;
-		}
 
 		if (map.containsKey("screenClient")) {
 			Client parent = sessionManager.getClientByPublicSID(parentSid, null);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
index 8ec7b27..0f8fc82 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
@@ -28,6 +28,10 @@ import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.apache.wicket.util.string.Strings;
+
+import com.github.openjson.JSONArray;
+import com.github.openjson.JSONObject;
 
 /**
  * Temporary class, later will be merged with {@link org.apache.openmeetings.db.entity.room.Client}
@@ -65,6 +69,7 @@ public class Client implements IClient {
 	private int mic = -1;
 	private int width = 0;
 	private int height = 0;
+	private long broadcastId = -1;
 
 	public Client(String sessionId, int pageId, Long userId, UserDao dao) {
 		this.sessionId = sessionId;
@@ -157,6 +162,16 @@ public class Client implements IClient {
 		return activities;
 	}
 
+	public boolean hasAnyActivity(Activity... aa) {
+		boolean res = false;
+		if (aa != null) {
+			for (Activity a : aa) {
+				res |= activities.contains(a);
+			}
+		}
+		return res;
+	}
+
 	public boolean hasActivity(Activity a) {
 		return activities.contains(a);
 	}
@@ -243,8 +258,9 @@ public class Client implements IClient {
 		return cam;
 	}
 
-	public void setCam(int cam) {
+	public Client setCam(int cam) {
 		this.cam = cam;
+		return this;
 	}
 
 	public boolean isMicEnabled() {
@@ -255,32 +271,45 @@ public class Client implements IClient {
 		return mic;
 	}
 
-	public void setMic(int mic) {
+	public Client setMic(int mic) {
 		this.mic = mic;
+		return this;
 	}
 
 	public int getWidth() {
 		return width;
 	}
 
-	public void setWidth(int width) {
+	public Client setWidth(int width) {
 		this.width = width;
+		return this;
 	}
 
 	public int getHeight() {
 		return height;
 	}
 
-	public void setHeight(int height) {
+	public Client setHeight(int height) {
 		this.height = height;
+		return this;
 	}
 
 	public String getRemoteAddress() {
 		return remoteAddress;
 	}
 
-	public void setRemoteAddress(String remoteAddress) {
+	public Client setRemoteAddress(String remoteAddress) {
 		this.remoteAddress = remoteAddress;
+		return this;
+	}
+
+	public long getBroadcastId() {
+		return broadcastId;
+	}
+
+	public Client setBroadcastId(long broadcastId) {
+		this.broadcastId = broadcastId;
+		return this;
 	}
 
 	@Override
@@ -313,6 +342,31 @@ public class Client implements IClient {
 		return true;
 	}
 
+	public JSONObject toJson() {
+		JSONObject u = new JSONObject();
+		if (user != null) {
+			JSONObject a = new JSONObject();
+			u.put("firstName", user.getFirstname())
+				.put("lastName", user.getLastname())
+				.put("address", a);
+			if (user.getAddress() != null) {
+				if (Strings.isEmpty(user.getFirstname()) && Strings.isEmpty(user.getLastname())) {
+					a.put("email", user.getAddress().getEmail());
+				}
+				a.put("country", user.getAddress().getCountry());
+			}
+		}
+		return new JSONObject()
+				.put("user", u)
+				.put("uid", uid)
+				.put("rights", new JSONArray(rights))
+				.put("activities", new JSONArray(activities))
+				.put("pod", pod)
+				.put("broadcastId", broadcastId)
+				.put("width", width)
+				.put("height", height);
+	}
+
 	@Override
 	public String toString() {
 		return "Client [uid=" + uid + ", sessionId=" + sessionId + ", pageId=" + pageId + ", userId=" + user.getId() + ", roomId=" + roomId

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-flash/src/main/flex/main.mxml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/main.mxml b/openmeetings-flash/src/main/flex/main.mxml
index 1e3867b..d731972 100644
--- a/openmeetings-flash/src/main/flex/main.mxml
+++ b/openmeetings-flash/src/main/flex/main.mxml
@@ -60,46 +60,72 @@
 		}
 
 		private function appInit(evt:Event):void {
-			var tla:Object = FlexGlobals.topLevelApplication;
-			debug("appInit()", tla.parameters);
-			audioOnly = 'true' == tla.parameters['audioOnly'];
-			interview = 'true' == tla.parameters['interview'];
-			var _fps:int = parseInt(tla.parameters['fps']);
+			var params:Object = FlexGlobals.topLevelApplication.parameters;
+			debug("appInit()", params);
+			audioOnly = 'true' == params.audioOnly;
+			interview = 'true' == params.interview;
+			var _fps:int = parseInt(params.fps);
 			FPS = (isNaN(_fps) || _fps < 1 ? 30 : _fps);
-			video = new OmVideo(videoDisplay, tla.parameters);
-
-			ExternalInterface.addCallback("getDevices", function ():Object {
-				return {
-					cams: Camera.names
-					, mics: Microphone.names
-				};
-			});
-			ExternalInterface.addCallback("camChanged", function (val:int):void {
-				selectedCam = val;
-				camChanged(null);
-			});
-			ExternalInterface.addCallback("micChanged", function (val:int):void {
-				selectedMic = val;
-				camChanged(null);
-			});
-			ExternalInterface.addCallback("resChanged", function (width:int, height:int):void {
-				setResolution(width, height, true);
-			});
-			ExternalInterface.addCallback("close", function ():void {
-				video.reset();
-			});
-			ExternalInterface.addCallback("init", function (camIdx:int, micIdx:int, width:int, height:int):void {
-				selectedCam = camIdx;
-				selectedMic = micIdx;
-				setResolution(width, height, true);
-			});
-			ExternalInterface.addCallback("startRec", function ():void {
-				startTestRecording();
-			});
-			ExternalInterface.addCallback("play", function ():void {
-				playTestRecording();
-			});
-			ExternalInterface.call("VideoSettings.initSwf");
+			video = new OmVideo(videoDisplay, params);
+			switch (params.mode) {
+				case 'settings':
+				{
+					ExternalInterface.addCallback("getDevices", function ():Object {
+						return {
+							cams: Camera.names
+							, mics: Microphone.names
+						};
+					});
+					ExternalInterface.addCallback("camChanged", function (val:int):void {
+						selectedCam = val;
+						camChanged(null);
+					});
+					ExternalInterface.addCallback("micChanged", function (val:int):void {
+						selectedMic = val;
+						camChanged(null);
+					});
+					ExternalInterface.addCallback("resChanged", function (width:int, height:int):void {
+						setResolution(width, height, true);
+					});
+					ExternalInterface.addCallback("close", function ():void {
+						video.reset();
+					});
+					ExternalInterface.addCallback("init", function (camIdx:int, micIdx:int, width:int, height:int):void {
+						selectedCam = camIdx;
+						selectedMic = micIdx;
+						setResolution(width, height, true);
+					});
+					ExternalInterface.addCallback("startRec", function ():void {
+						startTestRecording();
+					});
+					ExternalInterface.addCallback("play", function ():void {
+						playTestRecording();
+					});
+					ExternalInterface.call("VideoSettings.initSwf");
+				}
+					break;
+				case OmVideo.BROADCAST:
+				{
+					selectedCam = params.cam;
+					selectedMic = params.mic;
+					video.resize(Math.max(300, params.width), Math.max(200, params.height));
+					attachCamera(function():void {
+						video.resize(params.width, params.height);
+						video.reset();
+						var cam:Camera = getCam();
+						video.attachCamera(cam);
+						video.broadcast(params.broadcastId, cam, getMic());
+						ExternalInterface.call("VideoManager.resetSize", params.uid);
+					});
+				}
+					break;
+				case OmVideo.PLAY:
+				{
+					video.resize(params.width, params.height);
+					video.play(params.broadcastId); // TODO audio/video
+				}
+					break;
+			}
 		}
 
 		private function uncaughtError(e:UncaughtErrorEvent):void {
@@ -160,7 +186,7 @@
 			return _camera;
 		}
 
-		private function attachCamera():void {
+		private function attachCamera(callback:Function):void {
 			if (!camAvail()) {
 				return;
 			}
@@ -179,13 +205,12 @@
 								debug("Unable to connect to active camera.");
 								break;
 							case 'Camera.Unmuted':
-								ExternalInterface.call("VideoSettings.allowRec", true);
-								_attachCamera(getCam());
+								callback();
 								break;
 						}
 					});
 				} else {
-					_attachCamera(cam);
+					callback();
 				}
 			} else {
 				var _mic:Microphone = getMic();
@@ -226,6 +251,11 @@
 			}
 		}
 
+		private function settingsCameraCallback():void {
+			ExternalInterface.call("VideoSettings.allowRec", true);
+			_attachCamera(getCam());
+		}
+
 		private function setResolution(width:int, height:int, attach:Boolean):void {
 			if (!interview) {
 				debug("onselect WxH :: " + width + "x" + height);
@@ -233,17 +263,17 @@
 				video.resize(width, height);
 
 				if (attach) {
-					attachCamera();
+					attachCamera(settingsCameraCallback);
 				}
 			}
 		}
 
 		private function camChanged(e:Event):void {
-			attachCamera();
+			attachCamera(settingsCameraCallback);
 		}
 
 		private function playTestRecording():void {
-			video.play(recName);
+			video.play(recName + ".flv");
 		}
 
 		private function startTestRecording():void {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
index cbc0ffe..e23e1ac 100644
--- a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
+++ b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
@@ -145,7 +145,7 @@ public class OmVideo {
 			}
 			videoStreamSettings.setQuality(cam.bandwidth, cam.quality);
 			videoStreamSettings.setKeyFrameInterval(cam.keyFrameInterval);
-			debug("::keyFrameInterval " + cam.keyFrameInterval);
+			debug("::camera settings ", cam.keyFrameInterval, cam.width, cam.height, cam.fps);
 			videoStreamSettings.setMode(cam.width, cam.height, cam.fps);
 			ns.videoStreamSettings = videoStreamSettings;
 		}
@@ -160,7 +160,7 @@ public class OmVideo {
 		}
 	}
 
-	private function publish(mode:String, name:String, cam:Camera, mic:Microphone, f:Function):void {
+	private function connect(callback:Function):void {
 		if (nc == null || !nc.connected) {
 			var url:String = params.url;  //TODO fallback
 			debug("NetConnection is not connected", url);
@@ -168,7 +168,7 @@ public class OmVideo {
 			nc.addEventListener(NetStatusEvent.NET_STATUS, function onConnectionStatus(e:NetStatusEvent):void {
 				debug("ConnectionStatus: " + e.info.code);
 				if (e.info.code == "NetConnection.Connect.Success") {
-					_publish(mode, name, cam, mic, f);
+					callback();
 				} else {
 					//TODO
 				}
@@ -197,27 +197,37 @@ public class OmVideo {
 				, nativeSsl: 'best' == params.proxyType
 			});
 		} else {
-			_publish(mode, name, cam, mic, f);
+			callback();
 		}
 	}
 
+	public function broadcast(name:String, cam:Camera, mic:Microphone):void {
+		connect(function():void {
+			_publish(BROADCAST, name, cam, mic, null);
+		});
+	}
+
 	public function record(name:String, cam:Camera, mic:Microphone, f:Function):void {
-		publish(RECORD, name, cam, mic, f);
+		connect(function():void {
+			_publish(RECORD, name, cam, mic, f);
+		});
 	}
 
 	public function play(name:String):void {
-		debug("PLAY::", name);
-		if (ns != null){
-			reset();
-		}
-		mode = PLAY;
-		createStream();
-		//invokes Method in baseVideoView which shows the stream
-		getVideo().attachNetStream(ns);
-		//FIXME: Commented out, cause this leads to Buffer-Full/Buffer-Empty Events
-		//after re-syncing the stream
-		//this.setBuffer(0.1);
-		ns.play(name + ".flv");
+		connect(function():void {
+			debug("PLAY::", name);
+			if (ns != null){
+				reset();
+			}
+			mode = PLAY;
+			createStream();
+			//invokes Method in baseVideoView which shows the stream
+			getVideo().attachNetStream(ns);
+			//FIXME: Commented out, cause this leads to Buffer-Full/Buffer-Empty Events
+			//after re-syncing the stream
+			//this.setBuffer(0.1);
+			ns.play(name);
+		});
 	}
 
 	public function reset():void {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 0f361dd..271f119 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -137,7 +137,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 		//chain of Resource Loaders, if not found it will search in Wicket's internal
 		//Resource Loader for a the property key
 		getResourceSettings().getStringResourceLoaders().add(0, new LabelResourceLoader());
-		getJavaScriptLibrarySettings().setJQueryReference(JQueryResourceReference.getV3());
+		getJavaScriptLibrarySettings().setJQueryReference(JQueryResourceReference.getV2());
 
 		super.init();
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
index 3055c86..b4da5e9 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
@@ -63,6 +63,7 @@ import org.apache.openmeetings.web.user.UserInfoDialog;
 import org.apache.openmeetings.web.user.chat.ChatPanel;
 import org.apache.openmeetings.web.user.rooms.RoomEnterBehavior;
 import org.apache.openmeetings.web.util.ContactsHelper;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.openmeetings.web.util.OmUrlFragment;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
@@ -127,10 +128,29 @@ public class MainPanel extends Panel {
 		super(id);
 		this.panel = _panel;
 		setOutputMarkupId(true);
-		add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
 		menu = new MenuPanel("menu", getMainMenu());
 		contents = new WebMarkupContainer("contents");
-		add(contents.add(client == null ? EMPTY : _panel).setOutputMarkupId(true).setMarkupId("contents"));
+		add(chat = new ChatPanel("chatPanel"));
+		add(newMessage = new MessageDialog("newMessageDialog", new CompoundPropertyModel<>(new PrivateMessage())) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onClose(IPartialPageRequestHandler handler, DialogButton button) {
+				BasePanel bp = getCurrentPanel();
+				if (send.equals(button) && bp != null) {
+					bp.onNewMessageClose(handler);
+				}
+			}
+		});
+		add(userInfo = new UserInfoDialog("userInfoDialog", newMessage));
+		add(new OmAjaxClientInfoBehavior());
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
+		add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
+		add(contents.add(client == null ? EMPTY : panel).setOutputMarkupId(true).setMarkupId("contents"));
 		topControls.add(menu.setVisible(false), topLinks.setVisible(false).setOutputMarkupPlaceholderTag(true).setMarkupId("topLinks"));
 		topLinks.add(new AjaxLink<Void>("messages") {
 			private static final long serialVersionUID = 1L;
@@ -157,24 +177,21 @@ public class MainPanel extends Panel {
 				about.open(target);
 			}
 		});
+		add(about);
 		if (getApplication().getDebugSettings().isDevelopmentUtilitiesEnabled()) {
 			add(new DebugBar("dev").setOutputMarkupId(true));
 		} else {
 			add(new EmptyPanel("dev").setVisible(false));
 		}
-		add(about, chat = new ChatPanel("chatPanel"));
-		add(newMessage = new MessageDialog("newMessageDialog", new CompoundPropertyModel<>(new PrivateMessage())) {
+		topLinks.add(new ConfirmableAjaxBorder("logout", getString("310"), getString("634")) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			public void onClose(IPartialPageRequestHandler handler, DialogButton button) {
-				BasePanel bp = getCurrentPanel();
-				if (send.equals(button) && bp != null) {
-					bp.onNewMessageClose(handler);
-				}
+			protected void onSubmit(AjaxRequestTarget target) {
+				getSession().invalidate();
+				setResponsePage(Application.get().getSignInPageClass());
 			}
 		});
-		add(userInfo = new UserInfoDialog("userInfoDialog", newMessage));
 		add(new AbstractDefaultAjaxBehavior() {
 			private static final long serialVersionUID = 1L;
 
@@ -224,9 +241,9 @@ public class MainPanel extends Panel {
 			@Override
 			protected void onConnect(ConnectedMessage msg) {
 				super.onConnect(msg);
+				ExtendedClientProperties cp = WebSession.get().getExtendedProperties();
 				client = new Client(getSession().getId(), msg.getKey().hashCode(), getUserId(), getBean(UserDao.class));
-				client.setRemoteAddress(WebSession.get().getClientInfo().getProperties().getRemoteAddress());
-				addOnlineUser(client);
+				addOnlineUser(cp.update(client));
 				log.debug("WebSocketBehavior::onConnect [uid: {}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
 			}
 
@@ -268,21 +285,6 @@ public class MainPanel extends Panel {
 				}
 			}
 		});
-		add(new OmAjaxClientInfoBehavior());
-	}
-
-	@Override
-	protected void onInitialize() {
-		super.onInitialize();
-		topLinks.add(new ConfirmableAjaxBorder("logout", getString("310"), getString("634")) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			protected void onSubmit(AjaxRequestTarget target) {
-				getSession().invalidate();
-				setResponsePage(Application.get().getSignInPageClass());
-			}
-		});
 	}
 
 	private static int getLevel() {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
index 9ec4dea..8e4f8c6 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
@@ -153,9 +153,10 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 					@Override
 					protected void onClientInfo(AjaxRequestTarget target, WebClientInfo info) {
 						super.onClientInfo(target, info);
+						ExtendedClientProperties cp = (ExtendedClientProperties)info.getProperties();
 						target.appendJavaScript(
-								VideoSettings.getInitScript((ExtendedClientProperties)info.getProperties(), "hibernate", "networktest")
-								.append("VideoSettings.open();"));
+								String.format("VideoSettings.init(%s);VideoSettings.open();"
+										, VideoSettings.getInitJson(cp, "hibernate", "noclient")));
 					}
 				}));
 				error = false;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
index 80fae9f..87afb87 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
@@ -42,5 +42,10 @@
 	<div id="disconnected-dlg" wicket:message="title:204, data-reload:753" style="display:none">
 		<wicket:message key="556"/>
 	</div>
+	<div style="display:none">
+		<div id="user-video">
+			<div class="video"></div>
+		</div>
+	</div>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index c4d9728..abb98dc 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -25,6 +25,7 @@ import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getOnlineClient;
 import static org.apache.openmeetings.web.app.Application.getRoomClients;
 import static org.apache.openmeetings.web.app.WebSession.getDateFormat;
+import static org.apache.openmeetings.web.app.WebSession.getSid;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 
 import java.util.Calendar;
@@ -81,6 +82,7 @@ import org.apache.wicket.request.resource.ResourceReference;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
+import com.github.openjson.JSONObject;
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
 import com.googlecode.wicket.jquery.ui.interaction.droppable.Droppable;
@@ -115,7 +117,10 @@ public class RoomPanel extends BasePanel {
 					, getUserId(), "0", r.getId()
 					, cp.getRemoteAddress()
 					, "" + r.getId());
-			target.appendJavaScript(VideoSettings.getInitScript(cp, "" + r.getId(), getClient().getUid()));
+			//TODO add all broadcasting clients
+			JSONObject options = VideoSettings.getInitJson(cp, "" + r.getId(), getClient().getUid());
+			options.put("interview", Room.Type.interview == r.getType());
+			target.appendJavaScript(String.format("VideoManager.init(%s);", options));
 			WebSocketHelper.sendRoom(new RoomMessage(r.getId(), getUserId(), RoomMessage.Type.roomEnter));
 			getMainPanel().getChat().roomEnter(r, target);
 			if (r.isFilesOpened()) {
@@ -354,9 +359,14 @@ public class RoomPanel extends BasePanel {
 						}
 						break;
 					case rightUpdated:
-						sidebar.update(handler);
-						menu.update(handler);
-						wb.update(handler);
+						{
+							Client c = getOnlineClient(((TextRoomMessage)m).getText());
+							handler.appendJavaScript(String.format("VideoManager.update(%s);"
+									, c.toJson().put("sid", getSid()).put("self", getClient().getUid().equals(c.getUid()))));
+							sidebar.update(handler);
+							menu.update(handler);
+							wb.update(handler);
+						}
 						break;
 					case roomEnter:
 						sidebar.update(handler);
@@ -581,7 +591,7 @@ public class RoomPanel extends BasePanel {
 	}
 
 	public void broadcast(Client client) {
-		WebSocketHelper.sendRoom(new RoomMessage(getRoom().getId(), getUserId(), RoomMessage.Type.rightUpdated));
+		WebSocketHelper.sendRoom(new TextRoomMessage(getRoom().getId(), getUserId(), RoomMessage.Type.rightUpdated, client.getUid()));
 		RoomBroadcaster.sendUpdatedClient(client);
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
index 98319fc..0b9a08c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
@@ -65,12 +65,12 @@ public class VideoSettings extends Panel {
 		return String.format("%s://%s:%s/%s", protocol, host, port, app);
 	}
 
-	public static StringBuilder getInitScript(ExtendedClientProperties cp, String scope, String uid) {
+	public static JSONObject getInitJson(ExtendedClientProperties cp, String scope, String uid) {
 		JSONObject gs = getBean(ScopeApplicationAdapter.class).getFlashSettings();
 		JSONObject s = new JSONObject()
 				.put(FLASH_VIDEO_CODEC, gs.get(FLASH_VIDEO_CODEC))
 				.put(FLASH_FPS, gs.get(FLASH_FPS))
-				.put("SID", WebSession.getSid())
+				.put("sid", WebSession.getSid())
 				.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct");
 		if (!Strings.isEmpty(uid)) {
 			s.put("uid", uid);
@@ -90,6 +90,6 @@ public class VideoSettings extends Panel {
 		} catch (Exception e) {
 			log.error("Error while constructing video settings parameters", e);
 		}
-		return new StringBuilder("VideoSettings.init(").append(s.toString()).append(");");
+		return s;
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index 989aa20..ffbfc79 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -16,6 +16,99 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+var Video = (function() {
+	var self = {}, c, box, v, vc, t, swf;
+
+	function _getName() {
+		return c.user.firstName + ' ' + c.user.lastName;
+	}
+	function _resetSize() {
+		v.dialog("option", "width", c.width).dialog("option", "height", t.height() + c.height + 2);
+		vc.width(c.width).height(c.height);
+		swf.attr('width', c.width).attr('height', c.height);
+	}
+	function _init(_box, _c) {
+		c = _c;
+		box = _box;
+		var _id = "video" + c.uid, name = _getName()
+			, w = c.self ? Math.max(300, c.width) : c.width
+			, h = c.self ? Math.max(200, c.height) : c.height;
+		box.append($('#user-video').clone().attr('id', _id).attr('title', name).data(self));
+		v = $('#' + _id);
+		v.dialog({
+			classes: {
+				'ui-dialog': 'ui-corner-all video user-video'
+				, 'ui-dialog-titlebar': 'ui-corner-all no-close'
+			}
+			, width: w
+			, minWidth: 40
+			, minHeight: 50
+			, autoOpen: true
+			, modal: false
+			//resizeStop
+		});
+		t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
+		vc = v.find('.video');
+		vc.width(w).height(h);
+		//broadcast
+		var o = VideoManager.getOptions();
+		if (c.self) {
+			o.cam = c.cam;
+			o.mic = c.mic;
+			o.mode = 'broadcast';
+		} else {
+			o.mode = 'play';
+		}
+		o.width = c.width;
+		o.height = c.height;
+		o.uid = c.uid;
+		o.sid = c.sid;
+		o.broadcastId = c.broadcastId;
+		swf = initVideo(vc, _id + '-swf', o);
+		swf.attr('width', w).attr('height', h);
+	}
+	function _update(_c) {
+		// TODO check, update video
+		c = _c;
+	}
+
+	self.update = _update;
+	self.init = _init;
+	self.resetSize = _resetSize;
+	return self;
+});
+var VideoManager = (function() {
+	var self = {}, box, options;
+
+	function _init(_options) {
+		options = _options;
+		VideoSettings.init(self.getOptions());
+		box = $('.room.box');
+	}
+	function _getVid(uid) {
+		return "video" + uid;
+	}
+	function _update(o) {
+		var _id = _getVid(o.uid)
+			, video = o.activities.indexOf('broadcastV') > -1
+			, audio = o.activities.indexOf('broadcastA') > -1
+			, av = audio || video
+			, v = $('#' + _id);
+		if (av && v.length != 1) {
+			Video().init(box, o);
+		} else if (av && v.length == 1) {
+			v.data().update(o);
+		} else if (!av && v.length == 1) {
+			v.remove();
+		}
+	}
+
+	self.getOptions = function() { return JSON.parse(JSON.stringify(options)); };
+	self.init = _init;
+	self.update = _update;
+	self.resetSize = function(uid) { $('#' + _getVid(uid)).data().resetSize(); };
+	return self;
+})();
 function setRoomSizes() {
 	var sb = $(".room.sidebar.left")
 		, w = $(window).width() - sb.width() - 5
@@ -73,6 +166,7 @@ function roomUnload() {
 		WbArea.destroy();
 	}
 	VideoSettings.close();
+	$('.ui-dialog.user-video').remove();
 }
 function startPrivateChat(el) {
 	Chat.addTab('chatTab-u' + el.parent().parent().data("userid"), el.parent().parent().find('.user.name').text());

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
index 9c96224..0a46761 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
@@ -41,7 +41,11 @@ var VideoSettings = (function() {
 		}
 	}
 	function _save() {
-		localStorage.setItem('openmeetings', JSON.stringify(s));
+		var _s = JSON.stringify(s);
+		localStorage.setItem('openmeetings', _s);
+		if (typeof avSettings === 'function') {
+			avSettings(_s);
+		}
 	}
 	function _init(options) {
 		vs = $('#video-settings');
@@ -85,6 +89,7 @@ var VideoSettings = (function() {
 		lm.progressbar({ value: 0 });
 		options.width = 300;
 		options.height = 200;
+		options.mode = 'settings';
 		swf = initVideo(vidScroll, 'video-settings-swf', options)[0];
 		vs.find('input, button').prop('disabled', true);
 		vs.find('button').button();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index ffa6ba1..62aaf2d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -27,6 +27,7 @@ import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.basic.Client.Pod;
@@ -34,6 +35,7 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.common.NameDialog;
@@ -41,6 +43,7 @@ import org.apache.openmeetings.web.room.RoomBroadcaster;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.openmeetings.web.room.VideoSettings;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -212,13 +215,9 @@ public class RoomSidebar extends Panel {
 		protected void respond(AjaxRequestTarget target) {
 			StringValue s = getRequest().getRequestParameters().getParameterValue(PARAM_SETTINGS);
 			if (!s.isEmpty()) {
-				JSONObject o = new JSONObject(s.toString());
+				ExtendedClientProperties cp = WebSession.get().getExtendedProperties();
 				Client c = room.getClient();
-				c.setCam(o.optInt("cam", -1));
-				c.setMic(o.optInt("mic", -1));
-				boolean interview = Room.Type.interview == room.getRoom().getType();
-				c.setWidth(interview ? 320 : o.optInt("width"));
-				c.setHeight(interview ? 260 : o.optInt("height"));
+				cp.setSettings(new JSONObject(s.toString())).update(c, Room.Type.interview == room.getRoom().getType());
 				if (!avInited) {
 					avInited = true;
 					if (Room.Type.conference == room.getRoom().getType()) {
@@ -419,6 +418,9 @@ public class RoomSidebar extends Panel {
 				//pod has changed, no need to toggle
 				c.set(a);
 			} else {
+				if (!c.hasActivity(Activity.broadcastV) && Activity.broadcastV == a) {
+					c.setBroadcastId(ScopeApplicationAdapter.nextBroadCastId());
+				}
 				c.toggle(a);
 			}
 			room.broadcast(c);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
index 1e339ae..a59cbbf 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
@@ -22,6 +22,8 @@ import static org.apache.openmeetings.web.app.Application.HASH_MAPPING;
 import static org.apache.openmeetings.web.app.Application.NOTINIT_MAPPING;
 import static org.apache.openmeetings.web.app.Application.SIGNIN_MAPPING;
 
+import org.apache.directory.api.util.Strings;
+import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.wicket.protocol.http.ClientProperties;
 import org.apache.wicket.request.IRequestParameters;
 
@@ -29,6 +31,10 @@ import com.github.openjson.JSONObject;
 
 public class ExtendedClientProperties extends ClientProperties {
 	private static final long serialVersionUID = 1L;
+	public static final String CAM = "cam";
+	public static final String MIC = "mic";
+	public static final String WIDTH = "width";
+	public static final String HEIGHT = "height";
 	private String baseUrl;
 	private String codebase;
 	private String settings;
@@ -41,13 +47,14 @@ public class ExtendedClientProperties extends ClientProperties {
 		return baseUrl;
 	}
 
-	public void setSettings(JSONObject s) {
+	public ExtendedClientProperties setSettings(JSONObject s) {
 		settings = s.toString();
+		return this;
 	}
 
 	public JSONObject getSettings() {
 		try {
-			return settings == null ? new JSONObject() : new JSONObject(settings.toString());
+			return Strings.isEmpty(settings) ? new JSONObject() : new JSONObject(settings.toString());
 		} catch (Exception e) {
 			//can throw, no op
 		}
@@ -81,4 +88,20 @@ public class ExtendedClientProperties extends ClientProperties {
 		codebase = sb.append("screenshare").toString();
 		settings = parameters.getParameterValue("settings").toString("{}");
 	}
+
+	public Client update(Client c) {
+		return update(c, false);
+	}
+
+	public Client update(Client c, boolean interview) {
+		JSONObject s = getSettings().optJSONObject("video");
+		if (s == null) {
+			s = new JSONObject();
+		}
+		return c.setRemoteAddress(getRemoteAddress())
+				.setCam(s.optInt(CAM, -1))
+				.setMic(s.optInt(MIC, -1))
+				.setWidth(interview ? 320 : s.optInt(WIDTH, 0))
+				.setHeight(interview ? 260 : s.optInt(HEIGHT, 0));
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index 36fab21..04d3a2b 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -352,7 +352,7 @@
 	font-weight: bold;
 	background-color: #00FF00;
 }
-.ui-dialog.video, .ui-dialog.video .ui-dialog-titlebar, .ui-dialog.video .video.ui-dialog-content {
+.ui-dialog.video, .ui-dialog.video .ui-dialog-titlebar, .ui-dialog.video .ui-dialog-content {
 	padding: 0;
 	overflow: hidden;
 }
@@ -574,3 +574,20 @@
 	border: 1px solid #888888;
 	box-shadow: 5px 5px 5px #888888;
 }
+.room.box .user-video {
+	display: inline-block !important;
+}
+.room.box .user-video .header {
+	height: 20px;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+}
+.room.box .user-video .header .ui-dialog-title {
+	padding-left: 5px;
+}
+.room.box .user-video .video {
+	min-width: 40px;
+	min-height: 30px;
+	overflow: hidden;
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bbcf269..48faea7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,7 @@
 		<db>derby</db>
 		<junit.version>4.12</junit.version>
 		<maven.javadoc.version>2.10.3</maven.javadoc.version>
-		<maven.surefire.version>2.19.1</maven.surefire.version>
+		<maven.surefire.version>2.20</maven.surefire.version>
 		<maven-site.version>3.3</maven-site.version>
 		<wicket.version>8.0.0-SNAPSHOT</wicket.version>
 		<wicketju.version>8.0.0-M5</wicketju.version>


[48/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] screen-sharing improved, build is fixed

Posted by so...@apache.org.
[OPENMEETINGS-551] screen-sharing improved, build is fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/bcfb736e
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/bcfb736e
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/bcfb736e

Branch: refs/heads/master
Commit: bcfb736ed62d53855dfd05d3df342db32c724ecd
Parents: a260f5a
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 23 14:57:40 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 23 14:57:40 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/core/remote/MobileService.java |   8 +-
 .../core/remote/RecordingService.java           |  10 +--
 .../core/remote/ScopeApplicationAdapter.java    |   9 +-
 .../core/session/SessionManager.java            |   2 +-
 .../openmeetings/core/util/RoomHelper.java      |   2 +-
 .../db/entity/room/StreamClient.java            |  44 +++++-----
 .../openmeetings/web/app/Application.java       |   4 +-
 .../apache/openmeetings/web/room/RoomPanel.java |  45 +++++-----
 .../web/room/menu/RoomMenuPanel.html            |   2 +
 .../org/apache/openmeetings/web/room/room.js    |  83 +++++++++++++------
 .../src/main/webapp/css/images/shared.png       | Bin 0 -> 1830 bytes
 openmeetings-web/src/main/webapp/css/room.css   |   3 +
 12 files changed, 121 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
index 3e571c2..a0d25fc 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
@@ -261,7 +261,7 @@ public class MobileService {
 				if (!Strings.isEmpty(c.getAvsettings()) && !c.isScreenClient()) {
 					Map<String, Object> map = new HashMap<>();
 					add(map, "streamId", c.getStreamid());
-					add(map, "broadCastId", c.getBroadCastID());
+					add(map, "broadCastId", c.getBroadCastId());
 					add(map, "userId", c.getUserId());
 					add(map, "firstname", c.getFirstname());
 					add(map, "lastname", c.getLastname());
@@ -339,7 +339,7 @@ public class MobileService {
 		StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		Map<String, Object> result = new HashMap<>();
 		result.put("publicSid", c.getPublicSID());
-		result.put("broadCastId", c.getBroadCastID());
+		result.put("broadCastId", c.getBroadCastId());
 		return result;
 	}
 
@@ -348,7 +348,7 @@ public class MobileService {
 		StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		c.setAvsettings(avMode);
 		if (!"n".equals(avMode)) {
-			c.setBroadCastID(nextBroadCastId());
+			c.setBroadCastId("" + nextBroadCastId());
 			c.setIsBroadcasting(true);
 		}
 		c.setVWidth(Double.valueOf(width).intValue());
@@ -362,7 +362,7 @@ public class MobileService {
 		hsm.put("message", new String[]{"avsettings", "0", avMode});
 		Map<String, Object> result = new HashMap<>();
 		if (!"n".equals(avMode)) {
-			result.put("broadcastId", c.getBroadCastID());
+			result.put("broadcastId", c.getBroadCastId());
 		}
 
 		scopeAdapter.sendMessageToCurrentScope("sendVarsToMessageWithClient", hsm, true, false);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
index e0bcd21..96a6f4f 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
@@ -165,7 +165,7 @@ public class RecordingService implements IPendingServiceCallback {
 						} else if (rcl.getAvsettings().equals("av") || rcl.getAvsettings().equals("a") || rcl.getAvsettings().equals("v")) {
 							// if the user does publish av, a, v
 							// But we only record av or a, video only is not interesting
-							String broadcastId = "" + rcl.getBroadCastID();
+							String broadcastId = rcl.getBroadCastId();
 							String streamName = generateFileName(recordingId, broadcastId);
 
 							// Add Meta Data
@@ -332,7 +332,7 @@ public class RecordingService implements IPendingServiceCallback {
 							}
 						} else if (rcl.getAvsettings().equals("av") || rcl.getAvsettings().equals("a") || rcl.getAvsettings().equals("v")) {
 
-							stopRecordingShow(scope, String.valueOf(rcl.getBroadCastID()).toString(), rcl.getRecordingMetaDataId());
+							stopRecordingShow(scope, rcl.getBroadCastId(), rcl.getRecordingMetaDataId());
 
 							// Update Meta Data
 							metaDataDao.updateEndDate(rcl.getRecordingMetaDataId(), new Date());
@@ -422,7 +422,7 @@ public class RecordingService implements IPendingServiceCallback {
 
 				// FIXME: Is there really a need to stop it manually if the user
 				// just stops the stream?
-				stopRecordingShow(scope, String.valueOf(rcl.getBroadCastID()), rcl.getRecordingMetaDataId());
+				stopRecordingShow(scope, rcl.getBroadCastId(), rcl.getRecordingMetaDataId());
 
 				// Update Meta Data
 				metaDataDao.updateEndDate(rcl.getRecordingMetaDataId(), new Date());
@@ -461,7 +461,7 @@ public class RecordingService implements IPendingServiceCallback {
 				// if the user does publish av, a, v
 				// But we only record av or a, video only is not interesting
 
-				String streamName = generateFileName(recordingId, String.valueOf(rcl.getBroadCastID()).toString());
+				String streamName = generateFileName(recordingId, rcl.getBroadCastId());
 
 				// Add Meta Data
 				boolean isAudioOnly = false;
@@ -477,7 +477,7 @@ public class RecordingService implements IPendingServiceCallback {
 						+ rcl.getLastname(), now, isAudioOnly, isVideoOnly, false, streamName, rcl.getInterviewPodId());
 
 				// Start FLV recording
-				recordShow(conn, String.valueOf(rcl.getBroadCastID()).toString(), streamName, metaDataId, false, recording.isInterview());
+				recordShow(conn, rcl.getBroadCastId(), streamName, metaDataId, false, recording.isInterview());
 
 				rcl.setRecordingMetaDataId(metaDataId);
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
index bfb251a..e8af7b1 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
@@ -588,10 +588,11 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			// In case its a screen sharing we start a new Video for that
 			if (c.isScreenClient()) {
 				c.setScreenPublishStarted(true);
+				c.setBroadCastId(stream.getPublishedName());
 				sessionManager.updateClientByStreamId(streamid, c, false, null);
 			}
 			if (!c.isMobile() && !Strings.isEmpty(c.getSecurityCode())) {
-				c.setBroadCastID(Long.parseLong(stream.getPublishedName()));
+				c.setBroadCastId(stream.getPublishedName());
 				c.setAvsettings("av");
 				c.setIsBroadcasting(true);
 				if (c.getVWidth() == 0 || c.getVHeight() == 0) {
@@ -680,8 +681,8 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 				log.debug("***  +++++++ ######## sendClientBroadcastNotifications Any Client is Recording - stop that");
 				recordingService.stopRecordingShowForClient(current.getScope(), rcl);
 			}
-			if (stream.getPublishedName().equals("" + rcl.getBroadCastID())) {
-				rcl.setBroadCastID(-1);
+			if (stream.getPublishedName().equals(rcl.getBroadCastId())) {
+				rcl.setBroadCastId("-1");
 				rcl.setIsBroadcasting(false);
 				rcl.setAvsettings("n");
 			}
@@ -1239,7 +1240,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		currentClient.setRoomEnter(new Date());
 		currentClient.setFirstname("SIP Transport");
 		currentClient.setLastname(getSipTransportLastname(roomId));
-		currentClient.setBroadCastID(Long.parseLong(broadCastId));
+		currentClient.setBroadCastId(broadCastId);
 		currentClient.setIsBroadcasting(true);
 		currentClient.setPublicSID(publicSID);
 		currentClient.setVWidth(120);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
index 84f2bf9..8af1814 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
@@ -213,7 +213,7 @@ public class SessionManager implements ISessionManager {
 			// get the corresponding user session object and update the settings
 			StreamClient rclUsual = getClientByPublicSID(rcm.getPublicSID(), server);
 			if (rclUsual != null) {
-				rclUsual.setBroadCastID(rcm.getBroadCastID());
+				rclUsual.setBroadCastId(rcm.getBroadCastId());
 				rclUsual.setAvsettings(rcm.getAvsettings());
 				rclUsual.setVHeight(rcm.getVHeight());
 				rclUsual.setVWidth(rcm.getVWidth());

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java
index 508bd4a..e74ce34 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java
@@ -33,7 +33,7 @@ public class RoomHelper {
 
 			json.put("screenShare", true)
 				.put("uid", sc.getPublicSID()) // unique screen-sharing ID
-				.put("broadcastId", sc.getBroadCastID())
+				.put("broadcastId", sc.getBroadCastId())
 				.put("width", sc.getVWidth())
 				.put("height", sc.getVHeight());
 		}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
index 2dc1fae..aba737a 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
@@ -46,22 +46,22 @@ import org.apache.openmeetings.util.CalendarPatterns;
  */
 @Entity
 @NamedQueries({
-	@NamedQuery(name = "deleteAll", query = "DELETE FROM Client"),
-	@NamedQuery(name = "deletedById", query = "DELETE FROM Client c WHERE c.id = :id"),
-	@NamedQuery(name = "deleteClientsByServer", query = "DELETE FROM Client c WHERE c.server = :server"),
-	@NamedQuery(name = "deletedByServerAndStreamId", query = "DELETE FROM Client c WHERE c.server = :server AND c.streamid LIKE :streamid"),
-	@NamedQuery(name = "countClients", query = "SELECT count(c.id) FROM Client c"),
-	@NamedQuery(name = "countClientsByServer", query = "SELECT count(c.id) FROM Client c WHERE c.server = :server"),
-	@NamedQuery(name = "countClientsByServerAndStreamId", query = "SELECT count(c.id) FROM Client c WHERE c.streamid LIKE :streamid AND c.server = :server"),
-	@NamedQuery(name = "getClientByServerAndStreamId", query = "SELECT c FROM Client c WHERE c.streamid LIKE :streamid AND c.server = :server"),
-	@NamedQuery(name = "getClientsByPublicSIDAndServer", query = "SELECT c FROM Client c WHERE c.publicSID LIKE :publicSID AND c.server = :server"),
-	@NamedQuery(name = "getClientsByPublicSID", query = "SELECT c FROM Client c WHERE c.publicSID LIKE :publicSID"),
-	@NamedQuery(name = "getClientsByServer", query = "SELECT c FROM Client c WHERE c.server = :server"),
-	@NamedQuery(name = "getClients", query = "SELECT c FROM Client c"),
-	@NamedQuery(name = "getClientsWithServer", query = "SELECT c FROM Client c LEFT JOIN FETCH c.server"),
-	@NamedQuery(name = "getClientsByUserId", query = "SELECT c FROM Client c WHERE c.server = :server AND c.userId = :userId"),
-	@NamedQuery(name = "getClientsByRoomId", query = "SELECT c FROM Client c WHERE c.roomId = :roomId"),
-	@NamedQuery(name = "getRoomsIdsByServer", query = "SELECT c.roomId FROM Client c WHERE c.server = :server GROUP BY c.roomId")
+	@NamedQuery(name = "deleteAll", query = "DELETE FROM StreamClient"),
+	@NamedQuery(name = "deletedById", query = "DELETE FROM StreamClient c WHERE c.id = :id"),
+	@NamedQuery(name = "deleteClientsByServer", query = "DELETE FROM StreamClient c WHERE c.server = :server"),
+	@NamedQuery(name = "deletedByServerAndStreamId", query = "DELETE FROM StreamClient c WHERE c.server = :server AND c.streamid LIKE :streamid"),
+	@NamedQuery(name = "countClients", query = "SELECT count(c.id) FROM StreamClient c"),
+	@NamedQuery(name = "countClientsByServer", query = "SELECT count(c.id) FROM StreamClient c WHERE c.server = :server"),
+	@NamedQuery(name = "countClientsByServerAndStreamId", query = "SELECT count(c.id) FROM StreamClient c WHERE c.streamid LIKE :streamid AND c.server = :server"),
+	@NamedQuery(name = "getClientByServerAndStreamId", query = "SELECT c FROM StreamClient c WHERE c.streamid LIKE :streamid AND c.server = :server"),
+	@NamedQuery(name = "getClientsByPublicSIDAndServer", query = "SELECT c FROM StreamClient c WHERE c.publicSID LIKE :publicSID AND c.server = :server"),
+	@NamedQuery(name = "getClientsByPublicSID", query = "SELECT c FROM StreamClient c WHERE c.publicSID LIKE :publicSID"),
+	@NamedQuery(name = "getClientsByServer", query = "SELECT c FROM StreamClient c WHERE c.server = :server"),
+	@NamedQuery(name = "getClients", query = "SELECT c FROM StreamClient c"),
+	@NamedQuery(name = "getClientsWithServer", query = "SELECT c FROM StreamClient c LEFT JOIN FETCH c.server"),
+	@NamedQuery(name = "getClientsByUserId", query = "SELECT c FROM StreamClient c WHERE c.server = :server AND c.userId = :userId"),
+	@NamedQuery(name = "getClientsByRoomId", query = "SELECT c FROM StreamClient c WHERE c.roomId = :roomId"),
+	@NamedQuery(name = "getRoomsIdsByServer", query = "SELECT c.roomId FROM StreamClient c WHERE c.server = :server GROUP BY c.roomId")
 })
 @Table(name = "client")
 @XmlRootElement
@@ -225,7 +225,7 @@ public class StreamClient implements IClient {
 	 * @see StreamClient#getBroadCastID()
 	 */
 	@Column(name = "broadcast_id")
-	private long broadCastID = -2;
+	private String broadCastId = "-2";
 
 	/**
 	 * @see StreamClient#getUserId()
@@ -629,12 +629,12 @@ public class StreamClient implements IClient {
 		this.avsettings = avsettings;
 	}
 
-	public long getBroadCastID() {
-		return broadCastID;
+	public String getBroadCastId() {
+		return broadCastId;
 	}
 
-	public void setBroadCastID(long broadCastID) {
-		this.broadCastID = broadCastID;
+	public void setBroadCastId(String broadCastId) {
+		this.broadCastId = broadCastId;
 	}
 
 	public String getPublicSID() {
@@ -888,7 +888,7 @@ public class StreamClient implements IClient {
 	@Override
 	public String toString() {
 		return "Client [streamid=" + streamid + ", publicSID=" + publicSID + ", isScreenClient=" + screenClient
-				+ ", isMobile = " + mobile + ", roomId=" + roomId + ", broadCastID=" + broadCastID + ", userId="
+				+ ", isMobile = " + mobile + ", roomId=" + roomId + ", broadCastID=" + broadCastId + ", userId="
 				+ userId + ", avsettings=" + avsettings + ", isRecording=" + isRecording + ", recordingId="
 				+ recordingId + ", recordingMetaDataId=" + recordingMetaDataId + ", screenPublishStarted="
 				+ screenPublishStarted + ", interviewPodId=" + interviewPodId + ", server=" + server + "]";

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 2718c5f..307124d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -323,13 +323,13 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 				}
 				if (!rcl.getIsBroadcasting() || hasVideo(rcl) != hasVideo(client)) {
 					rcl.setIsBroadcasting(true);
-					rcl.setBroadCastID(ScopeApplicationAdapter.nextBroadCastId());
+					rcl.setBroadCastId("" + ScopeApplicationAdapter.nextBroadCastId());
 				}
 				rcl.setAvsettings(sb.toString());
 			} else {
 				rcl.setAvsettings("n");
 				rcl.setIsBroadcasting(false);
-				rcl.setBroadCastID(-1L);
+				rcl.setBroadCastId("-1");
 			}
 		}
 		return rcl;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 6341021..59ea091 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -147,16 +147,11 @@ public class RoomPanel extends BasePanel {
 	private final WbPanel wb;
 	private String sharingUser = null;
 	private String recordingUser = null;
-	private String publishingUser = null; //TODO add
 
 	public RoomPanel(String id, Room r) {
 		super(id);
 		this.r = r;
 		this.wb = new WbPanel("whiteboard", this);
-		//TODO check here and set
-		//private String recordingUser = null;
-		//private String sharingUser = null;
-		//private String publishingUser = null;
 	}
 
 	private void initVideos(AjaxRequestTarget target) {
@@ -343,51 +338,51 @@ public class RoomPanel extends BasePanel {
 					case recordingStoped:
 						{
 							String uid = ((TextRoomMessage)m).getText();
-							if (Strings.isEmpty(uid) || !uid.equals(recordingUser)) {
-								log.error("Not existing/BAD user has stopped recording {} != {} !!!!", uid, recordingUser);
-							}
-							recordingUser = null;
-							menu.update(handler);
 							Client c = getOnlineClient(uid);
-							if (c == null) {
-								log.error("Not existing user has stopped recording {} !!!!", uid);
+							if (c == null || !c.hasActivity(Client.Activity.record)) {
+								log.error("Not existing/BAD user has stopped recording {} != {} !!!!", uid);
 								return;
 							}
+							recordingUser = null;
 							c.remove(Client.Activity.record);
+							menu.update(handler);
 						}
 						break;
 					case recordingStarted:
 						{
-							recordingUser = ((TextRoomMessage)m).getText();
-							menu.update(handler);
-							Client c = getOnlineClient(recordingUser);
+							String uid = ((TextRoomMessage)m).getText();
+							Client c = getOnlineClient(uid);
 							if (c == null) {
-								log.error("Not existing user has started recording {} !!!!", recordingUser);
+								log.error("Not existing user has started recording {} !!!!", uid);
 								return;
 							}
+							recordingUser = uid;
 							c.set(Client.Activity.record);
+							menu.update(handler);
 						}
 						break;
 					case sharingStoped:
 						{
-							sharingUser = null;
-							Client c = getOnlineClient(((TextRoomMessage)m).getText());
-							if (c == null) {
-								log.error("Not existing user has started sharing {} !!!!", sharingUser);
+							String uid = ((TextRoomMessage)m).getText();
+							Client c = getOnlineClient(uid);
+							if (c == null || !c.hasActivity(Client.Activity.share)) {
+								log.error("Not existing user has started sharing {} !!!!", uid);
 								return;
 							}
+							sharingUser = null;
 							c.remove(Client.Activity.share);
 							menu.update(handler);
 						}
 						break;
 					case sharingStarted:
 						{
-							sharingUser = ((TextRoomMessage)m).getText();
-							Client c = getOnlineClient(sharingUser);
+							String uid = ((TextRoomMessage)m).getText();
+							Client c = getOnlineClient(uid);
 							if (c == null) {
-								log.error("Not existing user has started sharing {} !!!!", sharingUser);
+								log.error("Not existing user has started sharing {} !!!!", uid);
 								return;
 							}
+							sharingUser = uid;
 							c.set(Client.Activity.share);
 							menu.update(handler);
 						}
@@ -652,7 +647,7 @@ public class RoomPanel extends BasePanel {
 		Room r = getRoom();
 		return Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing)
 				&& r.isAllowRecording() && getClient().hasRight(Right.share)
-				&& getSharingUser() == null;
+				&& sharingUser == null;
 	}
 
 	public RoomSidebar getSidebar() {
@@ -676,6 +671,6 @@ public class RoomPanel extends BasePanel {
 	}
 
 	public String getPublishingUser() {
-		return publishingUser;
+		return null;
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
index e8697bf..df5db12 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
@@ -22,6 +22,8 @@
 <wicket:panel>
 	<div wicket:id="menu"></div>
 	<div class="room menu right">
+		<span class="icon shared ui-button ui-corner-all ui-widget" wicket:message="data-user:692, data-text:850, data-view:848" 
+				role="button" style="display: none;"></span>
 		<span wicket:id="ask" class="icon ask"></span>
 		<span wicket:id="share" class="icon share"></span>
 		<span wicket:id="roomName" class="room name"></span>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index f9e1087..6581ef3 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -58,35 +58,37 @@ var Video = (function() {
 			icons: {
 				'collapse': 'ui-icon-minus'
 			}
-			, closable: false
+			, closable: !!c.screenShare
 			, collapsable: true
 			, dblclick: "collapse"
 		});
 		t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
-		v.parent().find('.ui-dialog-titlebar-buttonpane').append($('#video-volume-btn').children().clone());
-		var volume = v.parent().find('.dropdown-menu.video.volume');
-		v.parent().find('.ui-dialog-titlebar-volume').click(function(e) {
-			e.stopImmediatePropagation();
-			volume.toggle();
-		}).dblclick(function(e) {
-			e.stopImmediatePropagation();
-		});
-		var handle = v.parent().find('.slider .handle');
-		v.parent().find('.slider').slider({
-			orientation: 'vertical'
-			, range: 'min'
-			, min: 0
-			, max: 100
-			, value: 60
-			, slide: function(event, ui) {
-			}
-			, create: function() {
-				handle.text($(this).slider("value"));
-			}
-			, slide: function(event, ui) {
-				handle.text(ui.value);
-			}
-		});
+		if (!c.screenShare) {
+			v.parent().find('.ui-dialog-titlebar-buttonpane').append($('#video-volume-btn').children().clone());
+			var volume = v.parent().find('.dropdown-menu.video.volume');
+			v.parent().find('.ui-dialog-titlebar-volume').click(function(e) {
+				e.stopImmediatePropagation();
+				volume.toggle();
+			}).dblclick(function(e) {
+				e.stopImmediatePropagation();
+			});
+			var handle = v.parent().find('.slider .handle');
+			v.parent().find('.slider').slider({
+				orientation: 'vertical'
+				, range: 'min'
+				, min: 0
+				, max: 100
+				, value: 60
+				, slide: function(event, ui) {
+				}
+				, create: function() {
+					handle.text($(this).slider("value"));
+				}
+				, slide: function(event, ui) {
+					handle.text(ui.value);
+				}
+			});
+		}
 		vc = v.find('.video');
 		vc.width(_w).height(_h);
 		//broadcast
@@ -115,15 +117,17 @@ var Video = (function() {
 	self.update = _update;
 	self.init = _init;
 	self.resetSize = _resetSize;
+	self.client = function() { return c; };
 	return self;
 });
 var VideoManager = (function() {
-	var self = {}, box, options;
+	var self = {}, box, options, share;
 
 	function _init(_options) {
 		options = _options;
 		VideoSettings.init(self.getOptions());
 		box = $('.room.box');
+		share = box.find('.icon.shared.ui-button');
 	}
 	function _getVid(uid) {
 		return "video" + uid;
@@ -143,14 +147,39 @@ var VideoManager = (function() {
 		}
 	}
 	function _play(c) {
-		Video().init(box, options.uid, c);
+		if (!!c.screenShare) {
+			_highlight(share.attr('title', share.data('user') + ' ' + c.user.firstName + ' ' + c.user.lastName + ' ' + share.data('text')).show(), 10);
+			share.tooltip().click(function() {
+				var v = $('#' + _getVid(c.uid))
+				if (v.length != 1) {
+					Video().init(box, options.uid, c);
+				} else {
+					v.dialog('open');
+				}
+			});
+		} else {
+			Video().init(box, options.uid, c);
+		}
 	}
 	function _close(uid) {
 		var _id = _getVid(uid), v = $('#' + _id);
 		if (v.length == 1) {
+			if (v.data().client().screenShare) {
+				share.off('click').hide();
+			}
 			v.remove();
 		}
 	}
+	function _highlight(el, count) {
+		if (count < 0) {
+			return;
+		}
+		el.addClass('ui-state-highlight', 2000, function() {
+			el.removeClass('ui-state-highlight', 2000, function() {
+				_highlight(el, --count);
+			});
+		});
+	}
 
 	self.getOptions = function() { return JSON.parse(JSON.stringify(options)); };
 	self.init = _init;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-web/src/main/webapp/css/images/shared.png
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/images/shared.png b/openmeetings-web/src/main/webapp/css/images/shared.png
new file mode 100644
index 0000000..80c4edd
Binary files /dev/null and b/openmeetings-web/src/main/webapp/css/images/shared.png differ

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bcfb736e/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index cf437c1..66e71cb 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -79,6 +79,9 @@
 .room.menu.right .icon.share {
 	background-image: url(images/monitor_go.png);
 }
+.room.menu.right .icon.shared {
+	background-image: url(images/shared.png);
+}
 .room.menu.right .icon .profile {
 	margin-top: 3px;
 }


[33/50] [abbrv] openmeetings git commit: OPENMEETINGS-551 Minor changes: The video frame closes for other participants when the participant with video leaves the room.

Posted by so...@apache.org.
OPENMEETINGS-551 Minor changes: The video frame closes for other participants when the participant with video leaves the room.


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/ad9b33ba
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/ad9b33ba
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/ad9b33ba

Branch: refs/heads/master
Commit: ad9b33ba3155f130735a35b6c0163b74b19ab59f
Parents: d1c5df5
Author: Vasiliy Degtyarev <vd...@apache.org>
Authored: Tue Apr 18 04:41:23 2017 +0000
Committer: Vasiliy Degtyarev <vd...@apache.org>
Committed: Tue Apr 18 04:41:23 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/core/remote/ScopeApplicationAdapter.java      | 3 +++
 .../main/java/org/apache/openmeetings/web/app/Application.java | 6 +-----
 2 files changed, 4 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ad9b33ba/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
index 52f256d..676737e 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
@@ -507,6 +507,9 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			if (client.isScreenClient() && client.isStartStreaming()) {
 				//TODO check others/find better way
 				WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
+			} 
+			if (client.getIsBroadcasting()) {
+				WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.closeStream, client.getPublicSID()));
 			}
 
 			log.debug("removing Username " + client.getUsername() + " "

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ad9b33ba/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 8d7fcec..ac7cfa8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -60,7 +60,6 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.util.InitializationContainer;
 import org.apache.openmeetings.util.message.RoomMessage;
-import org.apache.openmeetings.util.message.TextRoomMessage;
 import org.apache.openmeetings.web.pages.AccessDeniedPage;
 import org.apache.openmeetings.web.pages.ActivatePage;
 import org.apache.openmeetings.web.pages.HashPage;
@@ -230,10 +229,8 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 
 	public static void exitRoom(Client c) {
 		Long roomId = c.getRoomId();
+		removeUserFromRoom(c);
 		if (roomId != null) {
-			if (hasVideo(c)){
-				sendRoom(new TextRoomMessage(c.getRoomId(), c.getUserId(), RoomMessage.Type.closeStream, c.getUid()));
-			}
 			sendRoom(new RoomMessage(roomId, c.getUserId(), RoomMessage.Type.roomExit));
 			getBean(ConferenceLogDao.class).add(
 					ConferenceLog.Type.roomLeave
@@ -241,7 +238,6 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 					, c.getRemoteAddress()
 					, "" + roomId);
 		}
-		removeUserFromRoom(c);
 	}
 
 	@Override


[07/50] [abbrv] openmeetings git commit: no jira: small issues in dashboard serialization are fixed

Posted by so...@apache.org.
no jira: small issues in dashboard serialization are fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/4e751aed
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/4e751aed
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/4e751aed

Branch: refs/heads/master
Commit: 4e751aedbbcfe014b4b7a864f01a86581de5d021
Parents: 7859e81
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 2 14:01:33 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 2 14:01:33 2017 +0000

----------------------------------------------------------------------
 .../apache/openmeetings/util/OmFileHelper.java  |  2 +-
 .../web/util/UserDashboardPersister.java        | 22 +++++++++++---------
 2 files changed, 13 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/4e751aed/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java
----------------------------------------------------------------------
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java
index 659bfec..8cf68d9 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OmFileHelper.java
@@ -95,7 +95,7 @@ public class OmFileHelper {
 	private static File getDir(File parent, String name) {
 		File f = new File(parent, name);
 		if (!f.exists()) {
-			f.mkdir();
+			f.mkdirs();
 		}
 		return f;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/4e751aed/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/UserDashboardPersister.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/UserDashboardPersister.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/UserDashboardPersister.java
index 0ab3242..d7dbfc9 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/UserDashboardPersister.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/UserDashboardPersister.java
@@ -27,6 +27,8 @@ import static org.red5.logging.Red5LoggerFactory.getLogger;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Collections;
 
 import org.slf4j.Logger;
@@ -39,7 +41,7 @@ import com.thoughtworks.xstream.io.xml.DomDriver;
 
 public class UserDashboardPersister implements DashboardPersister {
 	private static final Logger log = getLogger(UserDashboardPersister.class, webAppRootKey);
-	
+
 	@Override
 	public Dashboard load() {
 		return new XStreamDashboardPersister().load();
@@ -53,23 +55,23 @@ public class UserDashboardPersister implements DashboardPersister {
 	public static class XStreamDashboardPersister implements DashboardPersister {
 		private File file;
 		private XStream xstream;
-		
+
 		public XStreamDashboardPersister() {
 			this.file = getUserDashboard(getUserId());
-			
+
 			xstream = new XStream(new DomDriver(UTF_8.name()));
 			xstream.setMode(XStream.NO_REFERENCES);
 			xstream.alias("dashboard", UserDashboard.class);
 		}
-		
+
 		@Override
 		public Dashboard load() {
 			if (!file.exists() || !file.isFile()) {
 				return null;
 			}
-			
-			try {
-				return (Dashboard) xstream.fromXML(new FileInputStream(file));
+
+			try (InputStream is = new FileInputStream(file)) {
+				return (Dashboard) xstream.fromXML(is);
 			} catch (Exception e) {
 				log.error("Error while loading dashboard", e);
 				return null;
@@ -80,9 +82,9 @@ public class UserDashboardPersister implements DashboardPersister {
 		public void save(Dashboard dashboard) {
 			// sort widgets
 			Collections.sort(dashboard.getWidgets(), new WidgetComparator());
-			
-			try {
-				xstream.toXML(dashboard, new FileOutputStream(file));
+
+			try (OutputStream os = new FileOutputStream(file)) {
+				xstream.toXML(dashboard, os);
 			} catch (Exception e) {
 				log.error("Error while saving dashboard", e);
 			}


[43/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] video minimize and resize are added

Posted by so...@apache.org.
[OPENMEETINGS-551] video minimize and resize are added


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/c744c8bc
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/c744c8bc
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/c744c8bc

Branch: refs/heads/master
Commit: c744c8bca6a7667b5d223bbcf79054b271ad6c18
Parents: bb41646
Author: Maxim Solodovnik <so...@apache.org>
Authored: Thu Apr 20 01:07:53 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Thu Apr 20 01:07:53 2017 +0000

----------------------------------------------------------------------
 openmeetings-flash/src/main/flex/main.mxml               |  4 ++++
 .../src/main/flex/org/apache/openmeetings/OmVideo.as     |  6 ++++++
 .../apache/openmeetings/web/room/jquery.dialogextend.js  |  4 ++--
 .../openmeetings/web/room/jquery.dialogextend.min.js     |  2 +-
 .../main/java/org/apache/openmeetings/web/room/room.js   | 11 ++++-------
 5 files changed, 17 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c744c8bc/openmeetings-flash/src/main/flex/main.mxml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/main.mxml b/openmeetings-flash/src/main/flex/main.mxml
index d731972..f275526 100644
--- a/openmeetings-flash/src/main/flex/main.mxml
+++ b/openmeetings-flash/src/main/flex/main.mxml
@@ -126,6 +126,10 @@
 				}
 					break;
 			}
+			ExternalInterface.addCallback("vidResize", function (width:int, height:int):void {
+				video.resize(width, height);
+				video.vidResize(width, height);
+			});
 		}
 
 		private function uncaughtError(e:UncaughtErrorEvent):void {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c744c8bc/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
index e23e1ac..5538f46 100644
--- a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
+++ b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
@@ -67,6 +67,12 @@ public class OmVideo {
 		this.height = ui.height = height;
 	}
 
+	public function vidResize(width:int, height:int):void {
+		vid.width = width;
+		vid.height = height;
+		debug("OmVideo::resize", width, height);
+	}
+
 	public function attachCamera(cam:Camera):void {
 		getVideo().attachCamera(cam);
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c744c8bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js
index 7a605e9..fc60d0a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js
@@ -280,7 +280,7 @@
     collapse: function() {
       var newHeight, pos;
 
-      newHeight = $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height() + 15;
+      newHeight = $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height() + 2;
       this._trigger("beforeCollapse");
       if (this._state !== "normal") {
         this._restore();
@@ -292,7 +292,7 @@
         "height": newHeight,
         "maxHeight": newHeight,
         "position": [pos.left - $(document).scrollLeft(), pos.top - $(document).scrollTop()]
-      }).on('dialogclose', this._collapse_restore).hide().dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space", "nowrap").end().find(".ui-dialog-content");
+      }).on('dialogclose', this._collapse_restore).dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space", "nowrap").end().find(".ui-dialog-content");
       this._setState("collapsed");
       this._toggleButtons();
       return this._trigger("collapse");

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c744c8bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
index 7aaae95..4eb412e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
@@ -1,3 +1,3 @@
 /* Licensed MIT */
 /*! jquery-dialogextend 2.0.4 2014-07-08 */
-(function(){var i;i=jQuery,i.widget("ui.dialogExtend",{version:"2.0.4",modes:{},options:{closable:!0,dblclick:!1,titlebar:!1,icons:{close:"ui-icon-closethick",restore:"ui-icon-newwin"},load:null,beforeRestore:null,restore:null},_create:function(){return this._state="normal",i(this.element[0]).data("ui-dialog")||i.error("jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted"),this._verifyOptions(),this._initStyles(),this._initButtons(),this._initTitleBar(),this._setState("normal"),this._on("load",function(i){return console.log("test",i)}),this._trigger("load")},_setState:function(t){return i(this.element[0]).removeClass("ui-dialog-"+this._state).addClass("ui-dialog-"+t),this._state=t},_verifyOptions:function(){var t,e,o;!this.options.dblclick||this.options.dblclick in this.modes||(i.error("jQuery.dialogExtend Error : Invalid <dblclick> value '"+this.options.dblclick+"'"),this.options.dblclick=!1),this.options.titlebar&&"none"!==(e=this.options.titlebar)&&"transparent"
 !==e&&(i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'"),this.options.titlebar=!1),o=[];for(t in this.modes)this["_verifyOptions_"+t]?o.push(this["_verifyOptions_"+t]()):o.push(void 0);return o},_initStyles:function(){var t,e,o;i(".dialog-extend-css").length||(e="",e+='<style class="dialog-extend-css" type="text/css">',e+=".ui-dialog .ui-dialog-titlebar-buttonpane>a { float: right; }",e+=".ui-dialog .ui-dialog-titlebar-restore { width: 19px; height: 18px; }",e+=".ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }",e+=".ui-dialog .ui-dialog-titlebar-restore:hover,",e+=".ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }",e+=".ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }",e+="</style>",i(e).appendTo("body")),o=[];for(t in this.modes)o.push(this["_initStyles_"+t]());return o},_initButtons:function(){var t,e,o,n,a,l=this;n=i(this.element[0]).dialog("widget").find(".ui-dialog-title
 bar"),t=i('<div class="ui-dialog-titlebar-buttonpane"></div>').appendTo(n),t.css({position:"absolute",top:"50%",right:"0.3em","margin-top":"-10px",height:"18px"}),n.find(".ui-dialog-titlebar-close").css({position:"relative","float":"right",top:"auto",right:"auto",margin:0}).find(".ui-icon").removeClass("ui-icon-closethick").addClass(this.options.icons.close).end().appendTo(t).end(),t.append('<a class="ui-dialog-titlebar-restore ui-corner-all ui-state-default" href="#"><span class="ui-icon '+this.options.icons.restore+'" title="restore">restore</span></a>').find(".ui-dialog-titlebar-restore").attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-close").toggle(this.options.closable).end().find(".ui-dialog-titlebar-restore").hide().c
 lick(function(i){return i.preventDefault(),l.restore()}).end(),a=this.modes;for(o in a)e=a[o],this._initModuleButton(o,e);return n.dblclick(function(){return l.options.dblclick?"normal"!==l._state?l.restore():l[l.options.dblclick]():void 0}).select(function(){return!1})},_initModuleButton:function(t,e){var o,n=this;return o=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-buttonpane"),o.append('<a class="ui-dialog-titlebar-'+t+' ui-corner-all ui-state-default" href="#" title="'+t+'"><span class="ui-icon '+this.options.icons[t]+'">'+t+"</span></a>").find(".ui-dialog-titlebar-"+t).attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-"+t).toggle(this.options[e.option]).click(function(i){return i.preventDefault(),n[t]()})
 .end()},_initTitleBar:function(){var t;switch(this.options.titlebar){case!1:return 0;case"none":return i(this.element[0]).dialog("option","draggable")&&(t=i("<div />").addClass("ui-dialog-draggable-handle").css("cursor","move").height(5),i(this.element[0]).dialog("widget").prepend(t).draggable("option","handle",t)),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").find(".ui-dialog-title").html("&nbsp;").end().css({"background-color":"transparent","background-image":"none",border:0,position:"absolute",right:0,top:0,"z-index":9999}).end();case"transparent":return i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css({"background-color":"transparent","background-image":"none",border:0});default:return i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'")}},state:function(){return this._state},restore:function(){return this._trigger("beforeRestore"),this._restore(),this._toggleButtons(),this._trigger("restore")},_restore:
 function(){return"normal"!==this._state?(this["_restore_"+this._state](),this._setState("normal"),i(this.element[0]).dialog("widget").focus()):void 0},_saveSnapshot:function(){return"normal"===this._state?(this.original_config_resizable=i(this.element[0]).dialog("option","resizable"),this.original_config_draggable=i(this.element[0]).dialog("option","draggable"),this.original_size_height=i(this.element[0]).dialog("widget").outerHeight(),this.original_size_width=i(this.element[0]).dialog("option","width"),this.original_size_maxHeight=i(this.element[0]).dialog("option","maxHeight"),this.original_position_mode=i(this.element[0]).dialog("widget").css("position"),this.original_position_left=i(this.element[0]).dialog("widget").offset().left-i("body").scrollLeft(),this.original_position_top=i(this.element[0]).dialog("widget").offset().top-i("body").scrollTop(),this.original_titlebar_wrap=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css("white-space")):void 0},_loadSnapsho
 t:function(){return{config:{resizable:this.original_config_resizable,draggable:this.original_config_draggable},size:{height:this.original_size_height,width:this.original_size_width,maxHeight:this.original_size_maxHeight},position:{mode:this.original_position_mode,left:this.original_position_left,top:this.original_position_top},titlebar:{wrap:this.original_titlebar_wrap}}},_toggleButtons:function(t){var e,o,n,a,l,s;n=t||this._state,i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").toggle("normal"!==n).css({right:"1.4em"}).end(),a=this.modes;for(o in a)e=a[o],i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o).toggle(n!==e.state&&this.options[e.option]);l=this.modes,s=[];for(o in l)e=l[o],e.state===n?s.push(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").insertAfter(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o)).end()):s.push(void 0);return s}})}).call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dia
 logExtend.prototype,{modes:{collapse:{option:"collapsable",state:"collapsed"}},options:{collapsable:!1,icons:{collapse:"ui-icon-triangle-1-s"},beforeCollapse:null,collapse:null},collapse:function(){var t,e;return t=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height()+15,this._trigger("beforeCollapse"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),e=i(this.element[0]).dialog("widget").position(),i(this.element[0]).dialog("option",{resizable:!1,height:t,maxHeight:t,position:[e.left-i(document).scrollLeft(),e.top-i(document).scrollTop()]}).on("dialogclose",this._collapse_restore).hide().dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space","nowrap").end().find(".ui-dialog-content"),this._setState("collapsed"),this._toggleButtons(),this._trigger("collapse")},_restore_collapsed:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).show().dialog("widget").find(".ui-dialog-buttonpane:
 hidden").show().end().find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,height:t.size.height,maxHeight:t.size.maxHeight}).off("dialogclose",this._collapse_restore)},_initStyles_collapse:function(){var t;return i(".dialog-extend-collapse-css").length?void 0:(t="",t+='<style class="dialog-extend-collapse-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-collapse { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse:hover,",t+=".ui-dialog .ui-dialog-titlebar-collapse:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_collapse_restore:function(){return i(this).dialogExtend("restore")}})}.call(this);
\ No newline at end of file
+(function(){var i;i=jQuery,i.widget("ui.dialogExtend",{version:"2.0.4",modes:{},options:{closable:!0,dblclick:!1,titlebar:!1,icons:{close:"ui-icon-closethick",restore:"ui-icon-newwin"},load:null,beforeRestore:null,restore:null},_create:function(){return this._state="normal",i(this.element[0]).data("ui-dialog")||i.error("jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted"),this._verifyOptions(),this._initStyles(),this._initButtons(),this._initTitleBar(),this._setState("normal"),this._on("load",function(i){return console.log("test",i)}),this._trigger("load")},_setState:function(t){return i(this.element[0]).removeClass("ui-dialog-"+this._state).addClass("ui-dialog-"+t),this._state=t},_verifyOptions:function(){var t,e,o;!this.options.dblclick||this.options.dblclick in this.modes||(i.error("jQuery.dialogExtend Error : Invalid <dblclick> value '"+this.options.dblclick+"'"),this.options.dblclick=!1),this.options.titlebar&&"none"!==(e=this.options.titlebar)&&"transparent"
 !==e&&(i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'"),this.options.titlebar=!1),o=[];for(t in this.modes)this["_verifyOptions_"+t]?o.push(this["_verifyOptions_"+t]()):o.push(void 0);return o},_initStyles:function(){var t,e,o;i(".dialog-extend-css").length||(e="",e+='<style class="dialog-extend-css" type="text/css">',e+=".ui-dialog .ui-dialog-titlebar-buttonpane>a { float: right; }",e+=".ui-dialog .ui-dialog-titlebar-restore { width: 19px; height: 18px; }",e+=".ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }",e+=".ui-dialog .ui-dialog-titlebar-restore:hover,",e+=".ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }",e+=".ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }",e+="</style>",i(e).appendTo("body")),o=[];for(t in this.modes)o.push(this["_initStyles_"+t]());return o},_initButtons:function(){var t,e,o,n,a,l=this;n=i(this.element[0]).dialog("widget").find(".ui-dialog-title
 bar"),t=i('<div class="ui-dialog-titlebar-buttonpane"></div>').appendTo(n),t.css({position:"absolute",top:"50%",right:"0.3em","margin-top":"-10px",height:"18px"}),n.find(".ui-dialog-titlebar-close").css({position:"relative","float":"right",top:"auto",right:"auto",margin:0}).find(".ui-icon").removeClass("ui-icon-closethick").addClass(this.options.icons.close).end().appendTo(t).end(),t.append('<a class="ui-dialog-titlebar-restore ui-corner-all ui-state-default" href="#"><span class="ui-icon '+this.options.icons.restore+'" title="restore">restore</span></a>').find(".ui-dialog-titlebar-restore").attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-close").toggle(this.options.closable).end().find(".ui-dialog-titlebar-restore").hide().c
 lick(function(i){return i.preventDefault(),l.restore()}).end(),a=this.modes;for(o in a)e=a[o],this._initModuleButton(o,e);return n.dblclick(function(){return l.options.dblclick?"normal"!==l._state?l.restore():l[l.options.dblclick]():void 0}).select(function(){return!1})},_initModuleButton:function(t,e){var o,n=this;return o=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-buttonpane"),o.append('<a class="ui-dialog-titlebar-'+t+' ui-corner-all ui-state-default" href="#" title="'+t+'"><span class="ui-icon '+this.options.icons[t]+'">'+t+"</span></a>").find(".ui-dialog-titlebar-"+t).attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-"+t).toggle(this.options[e.option]).click(function(i){return i.preventDefault(),n[t]()})
 .end()},_initTitleBar:function(){var t;switch(this.options.titlebar){case!1:return 0;case"none":return i(this.element[0]).dialog("option","draggable")&&(t=i("<div />").addClass("ui-dialog-draggable-handle").css("cursor","move").height(5),i(this.element[0]).dialog("widget").prepend(t).draggable("option","handle",t)),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").find(".ui-dialog-title").html("&nbsp;").end().css({"background-color":"transparent","background-image":"none",border:0,position:"absolute",right:0,top:0,"z-index":9999}).end();case"transparent":return i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css({"background-color":"transparent","background-image":"none",border:0});default:return i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'")}},state:function(){return this._state},restore:function(){return this._trigger("beforeRestore"),this._restore(),this._toggleButtons(),this._trigger("restore")},_restore:
 function(){return"normal"!==this._state?(this["_restore_"+this._state](),this._setState("normal"),i(this.element[0]).dialog("widget").focus()):void 0},_saveSnapshot:function(){return"normal"===this._state?(this.original_config_resizable=i(this.element[0]).dialog("option","resizable"),this.original_config_draggable=i(this.element[0]).dialog("option","draggable"),this.original_size_height=i(this.element[0]).dialog("widget").outerHeight(),this.original_size_width=i(this.element[0]).dialog("option","width"),this.original_size_maxHeight=i(this.element[0]).dialog("option","maxHeight"),this.original_position_mode=i(this.element[0]).dialog("widget").css("position"),this.original_position_left=i(this.element[0]).dialog("widget").offset().left-i("body").scrollLeft(),this.original_position_top=i(this.element[0]).dialog("widget").offset().top-i("body").scrollTop(),this.original_titlebar_wrap=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css("white-space")):void 0},_loadSnapsho
 t:function(){return{config:{resizable:this.original_config_resizable,draggable:this.original_config_draggable},size:{height:this.original_size_height,width:this.original_size_width,maxHeight:this.original_size_maxHeight},position:{mode:this.original_position_mode,left:this.original_position_left,top:this.original_position_top},titlebar:{wrap:this.original_titlebar_wrap}}},_toggleButtons:function(t){var e,o,n,a,l,s;n=t||this._state,i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").toggle("normal"!==n).css({right:"1.4em"}).end(),a=this.modes;for(o in a)e=a[o],i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o).toggle(n!==e.state&&this.options[e.option]);l=this.modes,s=[];for(o in l)e=l[o],e.state===n?s.push(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").insertAfter(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o)).end()):s.push(void 0);return s}})}).call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dia
 logExtend.prototype,{modes:{collapse:{option:"collapsable",state:"collapsed"}},options:{collapsable:!1,icons:{collapse:"ui-icon-triangle-1-s"},beforeCollapse:null,collapse:null},collapse:function(){var t,e;return t=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height()+2,this._trigger("beforeCollapse"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),e=i(this.element[0]).dialog("widget").position(),i(this.element[0]).dialog("option",{resizable:!1,height:t,maxHeight:t,position:[e.left-i(document).scrollLeft(),e.top-i(document).scrollTop()]}).on("dialogclose",this._collapse_restore).dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space","nowrap").end().find(".ui-dialog-content"),this._setState("collapsed"),this._toggleButtons(),this._trigger("collapse")},_restore_collapsed:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).show().dialog("widget").find(".ui-dialog-buttonpane:hidden")
 .show().end().find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,height:t.size.height,maxHeight:t.size.maxHeight}).off("dialogclose",this._collapse_restore)},_initStyles_collapse:function(){var t;return i(".dialog-extend-collapse-css").length?void 0:(t="",t+='<style class="dialog-extend-collapse-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-collapse { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse:hover,",t+=".ui-dialog .ui-dialog-titlebar-collapse:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_collapse_restore:function(){return i(this).dialogExtend("restore")}})}.call(this);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c744c8bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index a828a44..cd182c0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -24,10 +24,10 @@ var Video = (function() {
 	}
 	function _resetSize(_w, _h) {
 		var w = _w || size.width, h = _h || size.height;
+		v.dialog("option", "width", w).dialog("option", "height", t.height() + h + 2);
 		_setSize(w, h);
 	}
 	function _setSize(w, h) {
-		v.dialog("option", "width", w).dialog("option", "height", t.height() + h + 2);
 		vc.width(w).height(h);
 		swf.attr('width', w).attr('height', h);
 	}
@@ -50,7 +50,9 @@ var Video = (function() {
 			, autoOpen: true
 			, modal: false
 			, resizeStop: function(event, ui) {
-				var i = 0;
+				var w = ui.size.width - 2, h = ui.size.height - t.height() - 4;
+				_setSize(w, h);
+				swf[0].vidResize(w, h);
 			}
 		}).dialogExtend({
 			icons: {
@@ -59,11 +61,6 @@ var Video = (function() {
 			, closable: false
 			, collapsable: true
 			, dblclick: "collapse"
-			, restore : function(evt, dlg) {
-				var w = c.self ? Math.max(300, size.width) : size.width
-					, h = c.self ? Math.max(200, size.height) : size.height;
-				_setSize(w, h);
-			}
 		});
 		t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
 		vc = v.find('.video');


[38/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1632] wicket AjaxDownload is used

Posted by so...@apache.org.
[OPENMEETINGS-1632] wicket AjaxDownload is used


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/7b108d94
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/7b108d94
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/7b108d94

Branch: refs/heads/master
Commit: 7b108d9458e278e73b5a5cebf00f0053b20a4e1e
Parents: ccca6bd
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 19 04:59:55 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 19 04:59:55 2017 +0000

----------------------------------------------------------------------
 .../web/admin/backup/BackupPanel.java           |  27 +++-
 .../web/admin/labels/LangPanel.java             |  31 +++--
 .../web/common/tree/DownloadMenuItem.java       |   4 +-
 .../web/common/tree/FileTreePanel.java          |  26 +++-
 .../web/room/menu/StartSharingButton.java       |  26 ++--
 .../openmeetings/web/user/record/VideoInfo.java |  29 ++++-
 .../openmeetings/web/util/AjaxDownload.java     | 128 -------------------
 .../openmeetings/web/util/ajax-download.js      |  23 ----
 8 files changed, 108 insertions(+), 186 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
index f804ba6..ff19b04 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
@@ -20,8 +20,10 @@ package org.apache.openmeetings.web.admin.backup;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
+import static org.apache.wicket.util.time.Duration.NONE;
 
 import java.io.File;
+import java.nio.file.Path;
 import java.text.DecimalFormat;
 import java.util.Date;
 
@@ -33,11 +35,11 @@ import org.apache.openmeetings.util.CalendarPatterns;
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.web.admin.AdminPanel;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.openmeetings.web.util.upload.BootstrapFileUploadBehavior;
 import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
+import org.apache.wicket.extensions.ajax.AjaxDownload;
 import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.CheckBox;
@@ -45,8 +47,9 @@ import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.markup.html.form.upload.FileUploadField;
 import org.apache.wicket.model.Model;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.resource.FileSystemResource;
 import org.apache.wicket.util.lang.Bytes;
-import org.apache.wicket.util.resource.FileResourceStream;
 import org.apache.wicket.util.time.Duration;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -106,7 +109,23 @@ public class BackupPanel extends AdminPanel {
 			setMaxSize(Bytes.bytes(maxBytes));
 
 			// Add a component to download a file without page refresh
-			final AjaxDownload download = new AjaxDownload();
+			final AjaxDownload download = new AjaxDownload(new IResource() {
+				private static final long serialVersionUID = 1L;
+
+				@Override
+				public void respond(Attributes attributes) {
+					new FileSystemResource(backupFile.toPath()) {
+						private static final long serialVersionUID = 1L;
+
+						@Override
+						protected ResourceResponse createResourceResponse(Attributes attr, Path path) {
+							ResourceResponse response = super.createResourceResponse(attr, path);
+							response.setCacheDuration(NONE);
+							return response;
+						}
+					}.respond(attributes);
+				}
+			});
 			add(download);
 			// add an download button
 			add(new AjaxButton("download", this) {
@@ -164,8 +183,6 @@ public class BackupPanel extends AdminPanel {
 					timer.stop(target);
 					target.add(progressBar.setVisible(false));
 
-					download.setFileName(backupFile.getName());
-					download.setResourceStream(new FileResourceStream(backupFile));
 					download.initiate(target);
 				}
 			}).setVisible(false).setOutputMarkupPlaceholderTag(true));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
index afef420..b280d8a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
@@ -38,20 +38,23 @@ import org.apache.openmeetings.web.common.PagedEntityListPanel;
 import org.apache.openmeetings.web.data.DataViewContainer;
 import org.apache.openmeetings.web.data.OmOrderByBorder;
 import org.apache.openmeetings.web.data.SearchableDataProvider;
-import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.openmeetings.web.util.upload.BootstrapFileUploadBehavior;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.extensions.ajax.AjaxDownload;
 import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.markup.html.form.upload.FileUploadField;
 import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.request.resource.ContentDisposition;
+import org.apache.wicket.request.resource.ResourceStreamResource;
 import org.apache.wicket.util.resource.AbstractResourceStream;
+import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -172,17 +175,18 @@ public class LangPanel extends AdminPanel {
 		});
 
 		// Add a component to download a file without page refresh
-		final AjaxDownload download = new AjaxDownload();
-		langForm.add(download);
-
-		langForm.add(new AjaxButton("export"){
+		final AjaxDownload download = new AjaxDownload(new ResourceStreamResource() {
 			private static final long serialVersionUID = 1L;
 
+			{
+				setContentDisposition(ContentDisposition.ATTACHMENT);
+			}
+
 			@Override
-			protected void onSubmit(AjaxRequestTarget target) {
+			protected IResourceStream getResourceStream(Attributes attributes) {
 				final String name = LabelDao.getLabelFileName(language.getValue());
-				download.setFileName(name);
-				download.setResourceStream(new AbstractResourceStream() {
+				setFileName(name);
+				return new AbstractResourceStream() {
 					private static final long serialVersionUID = 1L;
 					private transient InputStream is;
 
@@ -203,7 +207,16 @@ public class LangPanel extends AdminPanel {
 							is = null;
 						}
 					}
-				});
+				};
+			}
+		});
+		langForm.add(download);
+
+		langForm.add(new AjaxButton("export"){
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void onSubmit(AjaxRequestTarget target) {
 				download.initiate(target);
 
 				// repaint the feedback panel so that it is hidden

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/DownloadMenuItem.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/DownloadMenuItem.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/DownloadMenuItem.java
index e1c55f7..d94e86d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/DownloadMenuItem.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/DownloadMenuItem.java
@@ -30,7 +30,6 @@ import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.db.entity.file.FileItem.Type;
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.util.resource.FileResourceStream;
 
 import com.googlecode.wicket.jquery.ui.JQueryIcon;
 import com.googlecode.wicket.jquery.ui.widget.menu.MenuItem;
@@ -66,8 +65,7 @@ public class DownloadMenuItem extends MenuItem {
 					f = ff[0];
 				}
 			}
-			tree.downloader.setFileName(f.getName());
-			tree.downloader.setResourceStream(new FileResourceStream(f));
+			tree.dwnldFile = f;
 			tree.downloader.initiate(target);
 		}
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
index 37552d2..df9d056 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
@@ -23,7 +23,10 @@ import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG;
 import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_PDF;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
+import static org.apache.wicket.util.time.Duration.NONE;
 
+import java.io.File;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -41,19 +44,21 @@ import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.common.NameDialog;
-import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.attributes.CallbackParameter;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
+import org.apache.wicket.extensions.ajax.AjaxDownload;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.resource.FileSystemResource;
 
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
@@ -77,7 +82,24 @@ public abstract class FileTreePanel extends Panel {
 	private final WebMarkupContainer sizes = new WebMarkupContainer("sizes");
 	private FileItem lastSelected = null;
 	private Map<String, FileItem> selected = new HashMap<>();
-	final AjaxDownload downloader = new AjaxDownload();
+	File dwnldFile;
+	final AjaxDownload downloader = new AjaxDownload(new IResource() {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void respond(Attributes attributes) {
+			new FileSystemResource(dwnldFile.toPath()) {
+				private static final long serialVersionUID = 1L;
+
+				@Override
+				protected ResourceResponse createResourceResponse(Attributes attr, Path path) {
+					ResourceResponse response = super.createResourceResponse(attr, path);
+					response.setCacheDuration(NONE);
+					return response;
+				}
+			}.respond(attributes);
+		}
+	});
 	protected final IModel<String> homeSize = Model.of((String)null);
 	protected final IModel<String> publicSize = Model.of((String)null);
 	final ConvertingErrorsDialog errorsDialog = new ConvertingErrorsDialog("errors", Model.of((Recording)null));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
index 64801fa..1250eb5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
@@ -27,6 +27,7 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSH
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.WebSession.getLanguage;
+import static org.apache.wicket.util.time.Duration.NONE;
 
 import java.io.InputStream;
 
@@ -41,9 +42,11 @@ import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.OmButton;
 import org.apache.openmeetings.web.room.VideoSettings;
-import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.extensions.ajax.AjaxDownload;
+import org.apache.wicket.request.resource.ResourceStreamResource;
+import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -57,6 +60,7 @@ public class StartSharingButton extends OmButton {
 	private static final String CDATA_END = "]]>";
 	private final AjaxDownload download;
 	private final Client c;
+	private String app = "";
 
 	public StartSharingButton(String id, Client c) {
 		super(id);
@@ -64,20 +68,26 @@ public class StartSharingButton extends OmButton {
 		setOutputMarkupPlaceholderTag(true);
 		setVisible(false);
 		add(new AttributeAppender("title", Application.getString(1480)));
-		add(download = new AjaxDownload(true) {
+		add(download = new AjaxDownload(new ResourceStreamResource() {
 			private static final long serialVersionUID = 1L;
 
+			{
+				setFileName(String.format("public_%s.jnlp", StartSharingButton.this.c.getRoomId()));
+				setCacheDuration(NONE);
+			}
+
 			@Override
-			protected String getFileName() {
-				return String.format("public_%s.jnlp", StartSharingButton.this.c.getRoomId());
+			protected IResourceStream getResourceStream(Attributes attributes) {
+				StringResourceStream srs = new StringResourceStream(app, "application/x-java-jnlp-file");
+				srs.setCharset(UTF_8);
+				return srs;
 			}
-		});
+		}));
 	}
 
 	@Override
 	public void onClick(AjaxRequestTarget target) {
 		//TODO deny download in case other screen sharing is in progress
-		String app = "";
 		try (InputStream jnlp = getClass().getClassLoader().getResourceAsStream("APPLICATION.jnlp")) {
 			ConfigurationDao cfgDao = getBean(ConfigurationDao.class);
 			app = IOUtils.toString(jnlp, UTF_8);
@@ -108,10 +118,6 @@ public class StartSharingButton extends OmButton {
 					.replace("$allowRecording", "" + (room.isAllowRecording() && (0 == sessionManager.getRecordingCount(roomId))))
 					.replace("$allowPublishing", "" + (0 == sessionManager.getPublishingCount(roomId)))
 					;
-
-			StringResourceStream srs = new StringResourceStream(app, "application/x-java-jnlp-file");
-			srs.setCharset(UTF_8);
-			download.setResourceStream(srs);
 			download.initiate(target);
 		} catch (Exception e) {
 			log.error("Unexpected error while creating jnlp file", e);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
index a5a6285..792269a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
@@ -22,8 +22,10 @@ import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
 import static org.apache.openmeetings.util.OmFileHelper.getRecordingMetaData;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
+import static org.apache.wicket.util.time.Duration.NONE;
 
 import java.io.File;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -38,15 +40,16 @@ import org.apache.openmeetings.db.entity.record.Recording.Status;
 import org.apache.openmeetings.db.entity.record.RecordingMetaData;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.web.common.InvitationDialog;
-import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.AjaxDownload;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
-import org.apache.wicket.util.resource.FileResourceStream;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.resource.FileSystemResource;
 
 import com.googlecode.wicket.jquery.ui.JQueryIcon;
 import com.googlecode.wicket.jquery.ui.form.button.AjaxButton;
@@ -77,7 +80,24 @@ public class VideoInfo extends Panel {
 			}.start();
 		}
 	};
-	private final AjaxDownload download = new AjaxDownload();
+	private final AjaxDownload download = new AjaxDownload(new IResource() {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void respond(Attributes attributes) {
+			File f = rm.getObject().getFile(EXTENSION_MP4);
+			new FileSystemResource(f.toPath()) {
+				private static final long serialVersionUID = 1L;
+
+				@Override
+				protected ResourceResponse createResourceResponse(Attributes attr, Path path) {
+					ResourceResponse response = super.createResourceResponse(attr, path);
+					response.setCacheDuration(NONE);
+					return response;
+				}
+			}.respond(attributes);
+		}
+	});
 	private final IModel<Recording> rm = new CompoundPropertyModel<>(new Recording());
 	private final IModel<String> roomName = Model.of((String)null);
 	private boolean isInterview = false;
@@ -184,9 +204,6 @@ public class VideoInfo extends Panel {
 
 			@Override
 			public void onClick(AjaxRequestTarget target) {
-				File f = rm.getObject().getFile(EXTENSION_MP4);
-				download.setFileName(f.getName());
-				download.setResourceStream(new FileResourceStream(f));
 				download.initiate(target);
 			}
 		});

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/AjaxDownload.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/AjaxDownload.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/AjaxDownload.java
deleted file mode 100644
index c61c7d7..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/AjaxDownload.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.util;
-
-import java.util.UUID;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.Page;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.behavior.AbstractAjaxBehavior;
-import org.apache.wicket.markup.head.IHeaderResponse;
-import org.apache.wicket.markup.head.JavaScriptHeaderItem;
-import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
-import org.apache.wicket.markup.head.PriorityHeaderItem;
-import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
-import org.apache.wicket.request.resource.ContentDisposition;
-import org.apache.wicket.request.resource.JavaScriptResourceReference;
-import org.apache.wicket.request.resource.ResourceReference;
-import org.apache.wicket.util.resource.IResourceStream;
-
-/**
- * see: <a href="https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow">
- * https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow</href>
- * 
- */
-public class AjaxDownload extends AbstractAjaxBehavior {
-	private static final long serialVersionUID = 1L;
-	private boolean addAntiCache;
-	private String fileName;
-	private IResourceStream resourceStream;
-	private final String iframeId;
-
-	public AjaxDownload() {
-		this(true);
-	}
-
-	public AjaxDownload(boolean addAntiCache) {
-		super();
-		this.addAntiCache = addAntiCache;
-		iframeId = String.format("download-iframe-%s", UUID.randomUUID().toString());
-	}
-
-	/**
-	 * Call this method to initiate the download.
-	 */
-	public void initiate(AjaxRequestTarget target) {
-		StringBuilder url = new StringBuilder(getCallbackUrl());
-
-		if (addAntiCache) {
-			url.append(url.indexOf("?") > -1 ? "&" : "?")
-				.append("antiCache=").append(System.currentTimeMillis());
-		}
-		target.appendJavaScript(String.format("$('#%s').attr('src', '%s');", iframeId, url.toString()));
-	}
-
-	@Override
-	protected void onBind() {
-		super.onBind();
-		// it is impossible to get page by id anyway
-		if (!(getComponent() instanceof Page)) {
-			getComponent().setOutputMarkupId(true);
-		}
-	}
-
-	private static ResourceReference newResourceReference() {
-		return new JavaScriptResourceReference(AjaxDownload.class, "ajax-download.js");
-	}
-
-	@Override
-	public void renderHead(Component component, IHeaderResponse response) {
-		super.renderHead(component, response);
-		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(newResourceReference())));
-		response.render(OnDomReadyHeaderItem.forScript(String.format("addDwnldIframe('%s', '%s');", component instanceof Page ? "" : component.getMarkupId(), iframeId)));
-	}
-
-	@Override
-	public void onRequest() {
-		ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(getResourceStream(), getFileName());
-		handler.setContentDisposition(getContentDisposition());
-		getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
-	}
-
-	protected ContentDisposition getContentDisposition() {
-		return ContentDisposition.ATTACHMENT;
-	}
-	/**
-	 * Override this method for a file name which will let the browser prompt
-	 * with a save/open dialog.
-	 * 
-	 * @see ResourceStreamRequestTarget#getFileName()
-	 */
-	protected String getFileName() {
-		return this.fileName;
-	}
-
-	public void setFileName(String fileName) {
-		this.fileName = fileName;
-	}
-
-	/**
-	 * Hook method providing the actual resource stream.
-	 */
-	protected IResourceStream getResourceStream() {
-		return resourceStream;
-
-	}
-
-	public void setResourceStream(IResourceStream resourceStream) {
-		this.resourceStream = resourceStream;
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7b108d94/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ajax-download.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ajax-download.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ajax-download.js
deleted file mode 100644
index ee23529..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ajax-download.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-
-function addDwnldIframe(compId, id) {
-	compId = !!compId ? '#' + compId : 'body';
-	$(compId).append('<iframe id="' + id + '" style="display:none" src="about:blank"></iframe>');
-}


[50/50] [abbrv] openmeetings git commit: no jira: KEYS is placed in application

Posted by so...@apache.org.
no jira: KEYS is placed in application


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/a3379255
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/a3379255
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/a3379255

Branch: refs/heads/master
Commit: a3379255da2f2a9f6aab29e65c844e9f23f7d74f
Parents: ba868aa
Author: Maxim Solodovnik <so...@apache.org>
Authored: Fri Apr 28 02:52:39 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Fri Apr 28 02:52:39 2017 +0000

----------------------------------------------------------------------
 KEYS | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 181 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a3379255/KEYS
----------------------------------------------------------------------
diff --git a/KEYS b/KEYS
new file mode 100644
index 0000000..122ab85
--- /dev/null
+++ b/KEYS
@@ -0,0 +1,181 @@
+Edit this file in SVN at https://svn.apache.org/repos/asf/openmeetings/project/KEYS
+then update in /www/www.apache.org/dist/openmeetings/KEYS by logging in to people.apache.org
+and running:
+
+svn export http://svn.apache.org/repos/asf/openmeetings/project/KEYS /www/www.apache.org/dist/incubator/openmeetings/KEYS
+
+pub   2048R/93A30395 2011-12-20
+      Key fingerprint = BF13 CF11 F9C9 0CBE 4413  09AB 0055 16BF 93A3 0395
+uid                  Sebastian Wagner <se...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.17 (FreeBSD)
+
+mQENBE7wkxMBCADUdJh/1R6XHyUFQXi2qDr7YNPynHabpYSbzwCEivsMUZ093Sx5
+cDNSq7/f3ouozD5B5xV8J7Y4ju9eP/LHZLmzc7kUQpDm6XMz4U/6q6p7/QTNeyCX
+sj5Qv+AIAAKrbjaab9cPqEuwxtH6bsma/5KXsoQDQZwO54zUD0cMbcFw/ViRNLlk
+JpfpsWPooyLksgAsBIQcXvP4v3AsdzycqfCMoYgxVq0/J9KyHHxJmN0hyIC24yCM
+zLMrkkdl3azQ5xxuu3d1WUmCeNlTXlRsvEUAxSTMEFP07HlCqe3E4AczggZCpByY
+X24CL1DL/HtWIHZLEuulkXBYGdV0n2oxnHfHABEBAAG0KFNlYmFzdGlhbiBXYWdu
+ZXIgPHNlYmF3YWduZXJAYXBhY2hlLm9yZz6JATgEEwECACIFAk7wkxMCGw8GCwkI
+BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEABVFr+TowOVP9gH/2uA04/0PltWHpto
+0FTZyPOzSnPrJfvqUlbrxSEu0KzwcBMOjthIzeDgq4lGd74lZZYPP6mYHZvxwxrT
+uM6q3v+uWXsWtQt3T1ylUyrlD6zy2weCrxjPp2e4VYRh4UmBqZM46oE50dSCWWrj
+73RE6eiy4FOOo19Om3UqqLsSrEkcU+SnK497nOggYJBEdDIIedOTrXGHSIwQ7bpW
+IuQUm0sNUzEp605DiMmv0328YfNy1/iVQr2nVWpaL0jeUWUrDzugxee+EwAq7wnd
+awQAM4HUTRRHGV2UPLDgMlFQ3gy1nSB17PZqMj1WZik8mzEghLfHK2qpilICmwVQ
+U9obDGA=
+=7PK/
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub   4096R/D27B0B59 2012-08-07
+      Key fingerprint = 0ED1 419B B160 C9D5 DDA6  C727 4DED 03C4 D27B 0B59
+uid                  Eugen Schwert (CODE SIGNING KEY) <eu...@gmail.com>
+sub   4096R/A98ADBEE 2012-08-07
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.18 (FreeBSD)
+
+mQINBFAg22YBEADm48jAr7TjMbkhlVMYLlaE92mnyIyHrhcYUuFCPHG9MYfiPXNI
+/SlOSWYVbK8Ub10oIJu2TQCd/4ermpJv5qJXaxtACzLsK/C8kcOySveKQH1fVUnY
+s1msXbf1DfSWMFlysrJBYs1ly2bcv2eIysk9aJ3umuCXqz1BqJjG3P/o7KxMMMkf
+wQ1aWSimlzYWURuvlOjbPzsiKDmlIvWscP+BzbvnasdDhaJiqJo8s2kWznoJ7UQ3
+p6mf23UixDOPd/OVW/Pdr9a5X1RbzCvGvAkbqJImkrmkftnG/dY0qOrgQn5Tzpzc
+XSFt6yhKVt1/MoHzKcaUkGVFw+0dqZ+DIfGNiCM6TPhrgm/ZFupAQgAgGohIXEH5
+8nXl9+oARQt+75KH3ZlGLQJO/8ByBU9lPxYJnc9cjJkl3aZU3Qkk2Aeya0zEvpOU
+udGTp9sAc7SJ28cxN/19nWqygMQ7Ky+q6rzIuppMtEamSp3lGTsHxfoCTckr6uoI
+LGgUjuUKbau/rqy5tXsX+EjjxCCb7+g+DiZj5/Bt9RUWZZ0FBcy3RBKvgqOJ2aqV
+r76IpjiRqg7J8gWi2an1tnNoKM6mI7huRn0yj99aQ+3HB2TzpCArkN8sFdiydJ26
+jXJa2rB3VCVbZcLGkrovhDvuPu5zqNDjq7RmNIGwd1VH6Ke5BcEKo8R8CwARAQAB
+tDpFdWdlbiBTY2h3ZXJ0IChDT0RFIFNJR05JTkcgS0VZKSA8ZXVnZW4uc2Nod2Vy
+dEBnbWFpbC5jb20+iQI3BBMBAgAhAhsDAh4BAheABQJQIOQkBQsJCAcDBRUKCQgL
+BRYCAwEAAAoJEE3tA8TSewtZO8QQAMU8e3JIxXU+aeCG11jk+Qrilmy4rUNGO+0O
+6kd71XSN5IZQq57I0ys2NVDhsDobREunNetuD0gicRxmD0FVGeT8PBcpcRk2kcn6
+yLNBQzVp/+EvrX631dAG1xBaCo3MPV1KvbOtMw8kISHv2uWL1LAxZyOdLgiSq+hR
+GZxOWdAAOYpEOOtx9FlErUkdlQCm/YAJJAAmoqrwrIbQ5yJJgxmLaQhUvCW1kxeG
++gkLjZLUes4hru72i9V5iSTUu7hbUpOpI53Fklec2x4xmYeE0q4Lyx8bxADV/sEy
+Y4s9qatl0IMERT3unjnUJuiaRzL5/+TLyEveTafay2G6w17emDoRN0Gi4taYxgzv
+UJEaOAX6ucJFdx/Sv7O+8s9iETcsVZ/CC4ySUNYGsShpnhTEWdgC/gAqW25cXheR
+8a1wwwHYImZOFcQF80j0dKtx66A1TKF6F89vCwKuyYYmsNqm/jnjMja8qXdVetLq
+v3BW6XTrm79Aam3une6K9D3e1k9vnpLyO5mszRASLAAOP2Opew1kCK9VRMZILznt
+9Bkv4Zt609Fdrzlzvjii0+26a0/MCRW37t7Fw6bfaYxAZAYzxZJq3Gjfz6zEWAYk
+wcCdK54B0OzLxmMTV3yb4ihiJjmMFTgKT4+mPNN3+R3mCMt50AnHv+FYmwGPa7iJ
+wVvQ2Eo1uQINBFAg22YBEADPlSkqcFihAEJe7KtEAZnGNZSyhwDLAIO1C+oSCi+j
+k4czl8Jsv6vUBJsJzC3kQv9Qh6LL6e8dq8YE/L6oFAu9nkB4xoAiTo/3wasA6yAy
+TWGsDiXKG7K9QkO2Aprb2t8cM5feKR+fSR2EuK9x3e2RK9xZQSFnvJJASxJ2n1IG
+/3NioVb2mb/+CkQiVtnnbXlILCHNeWyKSvye0outvpy+IzLxBHowKKTa20KP7Sp3
+dJ3eQrACrUYnu6JNa3Yd1NHrlZfXlWTQmTFWseg8AsleaFpS5eMYHqhDuK5ZkqOm
+CyHR+udWCC4+DlqqZuCq1RgJC0AQAD5iNLoYHYHN4dikiPOteStYndW5W5eJmsNS
+k3Vqcdqwl0pMUMV9b8Y+FsFAhYyQtxREVnjEX8zhwp99kG4RO2uB/5phYr9ufwKO
+iLaGMrRU46P08HEnpqdLc8s4G2JFOju4m0qeq7TAimJ5KiM0SIbCqF3+xxosw06B
+vRZvoyXvwq+LjtAZLDbXpiLYyH38sIWuwaoOC0nYPPF4rq3mY23RsxTbTnHm37rI
+2J73XDUWRC9zL0gYtl+JBKPhRaTLc/vzCs41zqsll/jMtDpOP9cOAZ21AXGpoN0B
+XpW6jihqIUpSveFDHoR2tN4bYQbHcmD04MErqquJ495+28sxB7AG8qiRtkWm0uTY
+3wARAQABiQIfBBgBAgAJBQJQINtmAhsMAAoJEE3tA8TSewtZ6+cQAKlhT3On+FQL
+aS5HwZfwhU/cmuoNBrrP0eF5i5pilNcMfzDJPYKlWsupgqxJkDItd78SRODy7YN/
+gid1TJceAfib0jHr95tgwNxWkJMrtrPtppxcNLTHFB12uVoQKbrJkfl1qgBlo6cB
+MLhdJlPufGfTQ06ERnmCxcwrdT8HRN5WyvAkNd+RqAyMFfLWxbHRY+USrBtJAN7o
+TDV/613wgvsAvaPC/NBTFpYURbm9K9Y3B8nNqNWkPuyQMXqRdkPLy+ynnZJ7rbG8
+5aG/kQeDxvAwWN0oO5Ye9O4x2SYV8GyPD4UcHv+4sD6kDc91XD5D6P4JazB9QGfQ
+gGfigEqurnfAY0FDlqBDih1hiNg+KSZOtM9+x0y0mYul/Y1n3T99a6VURsV8zZyy
+9ev2q5vNHEsz5ynWOht+QkNgPQgndEJp5unRS8w+EMhi5Ee0qxnmUVjxurLqyQn8
+sCsfWM5Phj1XF8aTK/xq7S7c7a6/SLfMBISzRCTj51Su//TwqPxQqqPoJRXAJVG0
+1Gkd1kD7gaKgdqsyJe0UNk85SkL6W54BoIuX/7f5ygKYoiLdFHbUPStMrxReKxqa
+sZbkaBvtT6aBP/xRoDNTRbdQN620vWiFgyRkF+X5b8ARLZqcKZq1T+5wPSzzFqxH
+CaoyS9uK4WWsaeT4ML26sVhNQIFG3tpZ
+=AZYK
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub   4096R/C467526E 2012-08-09 [expires: 2017-08-08]
+      Key fingerprint = D3BF D979 E8D3 DD4B EDA6  1BC4 9E69 17B5 C467 526E
+uid                  Maxim Solodovnik (solomax) <so...@apache.org>
+sub   4096R/FDFEE7FE 2012-08-09 [expires: 2017-08-08]
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.18 (FreeBSD)
+
+mQINBFAjySoBEAC7ZQTyUxGqC7g0AC5feQNSNe5TAFUooGlGgag/aLhkl1ELVgxA
+5MysuLh2wpbA6NdpMYcZSwl+vEI7CrSEp3mWnqE1pwcdzNqs1XR6LHn9Tl/8gNwt
+oUj4QPSWPlDebUW3lIbdptbzMzfqm73GEUc71pal+QkyAYsD7fkdYIL3vnbZWI6Y
+i6nCFF6SzRkFUFOnbKXjTycoGe2EWncezD/Z1bWzzDHEqr/urIS2MMlLiZuIOKkr
+Yfb07zl02CmHOvrVOM+Yzza4ZRjTBoeOzNqWKfMpKwakezbF4gcQ+2NPdJjj1sw8
+QEzwmBFHBdgwexlwERoEynqUe2THGtInYj5gONtRK1WvAaXEr11iJtcsVmyYw+mi
+B8nJzATvh6J/Am814Lg3jd6RT/LSeAj5Y1JY2tCFljqAYTvudxvVLwllKwy01jJM
+76HoL27cnJZ1/ft7gmKCAv9GT+bXznZMVYiiOHBZ6hlQFqcPHIQlx/R+5dtCSbg7
+cBeBR0OM+As5pFm2RqOGfD3cPfMTGRFDNCiUr5Qda13XdiCEWsKUxyM4+iUfdz98
+hCvfLM2oehzXSbT33k5WM9hn1BPigy8YaKgq7CaJ9z5MYNa/nkda9JD57RuDW8zW
+rlphGPnjV+t5bj/IV25nPFc7a6iN4V+r8PSkyAwuzwGGcjJD3R8ppY4J2wARAQAB
+tC9NYXhpbSBTb2xvZG92bmlrIChzb2xvbWF4KSA8c29sb21heEBhcGFjaGUub3Jn
+PokCPgQTAQIAKAUCUCPJKgIbAwUJCWYBgAYLCQgHAwIGFQgCCQoLBBYCAwECHgEC
+F4AACgkQnmkXtcRnUm6EeBAAh8YSVNr1hMZav5InxUvj04SyhdwV7Zh4KEsxUciu
+/h1U0kXjWQVFjYpF5jb+v/YkI7PrB54ApZmOq+kAG6SNWYzDku6X8GCLrXHSN98/
+hpSGvMkjpIGCm69CniDZq0WWcBrGvEwFyx8I9TwHLzYHEG3h6eT1W94lak7CUzFp
+YjzDdrbiRJs7HtgKJou161gx0y+JkGWD80jJto5tC9IYYQWyNGqrKMmldNT4FS0w
+EkORh0yeU6/s4RpujofVTh+Vg0BwN7afGw3pKvu2cabnocEHXUYqtmk8RzqPbU7c
+Zxzmg9uqQKacCPz7xhjTlEzrW1fCW5N6SlDoZFHe+aH8o19wEB8QADODom5pbaA9
+s0Oy8lLlvVxPKpJC7ArPN+17KDLcuAv1/pMWoSZNbkCqTIa0+pszsfoysdpG1XRk
+K8g96dI8m2BaLUfmhEfxvhG3G5NxP5hMtQouQJhiuI0/sEVzLaddvKamRCvUruUE
+6MEFTB9C/P2b1igA5eXUCgO5wFqH6OYhmt0tyYi64jYdc4kUKPxD3tsnfEqD+Mk6
+ugDWYmJU3dGOJCy0lR96Lov2fc4D7qGcXsyVprNNysiLFZ/JvC5QH0nYrU9QqCCK
+rQ3bDZOB2nJBIvXQvxk3dNWJX5tnBKk4a5c6r8EOaeMhmUQgA7jG1dkMOL9SXZVt
+fHG5Ag0EUCPJKgEQALdS9RJZbLTpTRLGcIrx92cM0lBTiAm8IGooBnwMRtri9Az8
+qrNw+SZNTp4kmLP5niyAG9omXuM3UiSIgiE4JeyIEMZueKCwdOT0aXlqDAloremY
+spZ2c1rHTPrZCF9FJW2ycCd3Qt33eLsiE8QyvLrGWTp4EwNszdRz5MpV7TTccUOw
+vDi5GuKFNevnSkUUWN/c17bpyeSGDf9Dabl4rDW2/Gc+yQfMKu44gqDUaTR94Fvx
+OIupMtYR3H0vt4X1Fr2MapeKdc7/Xndldrd9zC+d1qEKe6/uUVDbOl8pNIkF/Zgi
+hANzqdN4HXqQDhO780dVQhKuTMAqE5CxLSj4sxjF9vC/sNtAf9taARmzBlsKtBmn
+uU/aldpaTUb33BMnHQ21vwwHVo5o7M7itKxgCLS06Kg2SyEpRsTFBuTGVDLceuly
+4KyHfnXOZFtnWYzYxrEMbDGi9x0PW1P38Gzk7YD9txzS3yj5oJF6QP0rmGlCJQGn
+iU/WRzhv0Gfpt1wYerodUedQn5qViht6GLpExMq6pxsBOFGzgE8I8bKdaJYhx5Ov
+8zCdUiSSoQgiBx8P6gzLwMZ52OMqkEWoXCsnCq3Fl1LZzpqv7nBRjuEklbQLdWCP
+WYHM6Yz7lQylproqnNQlbPfE59iA6ObD7V1UlORytifxaM8iPetI3dSoGANxABEB
+AAGJAiUEGAECAA8FAlAjySoCGwwFCQlmAYAACgkQnmkXtcRnUm5Jdw//Q+ct8W1H
+3J7AsO6HZ/6OpOzQu6W68VTVgY/akJb9hOPhRgd1/UN/18uoC36laS3YNDY33I6M
++5AkluAEkGwpLUAWfWHSD1zuwlgQVSYwNUGR+a0/LHFdrW7YP5CZ6XHGzqIszPTy
+2atQg+gdxnMyCZ8gMlKF6+DJwRdYoHLLGP9FLiifYn9GuMWaAVEVzcSmhm1L3N64
+satqV5eWmdXo8pclPy/iQH8XoKYoI3SHleJuwEAHp9syeVXC6KmltOmAZYQxTPtL
+NB0yr9MsTxI18dMJWsXTg8ZKcwrhssPSA5WQ7LigkjZNoX6W/O46Xm9OYQR003Br
+CJRRcCiiC3poAcH9nt9Nb2fIXDFoLcq02/x00V7TKxPvflBK3DFP6MSy8U6jkSUx
+hp2cQJY/eGSNYEc6UYOpMM2G5XLdvD0e7/Fvmpii0YvC5fKoXvO5pvl1H4RDJeRm
+I7csCb9DvX7Aj57V9FPpwT+UppeOaswSUhpPtjg/nv+ytZ005EE2RXU87jgEhCdX
+AzuZbTJxsoJgwT3ib+6lJVcxr7gU0lUYJ1gViPjx35Asb2najwrjQ7pNlLeTwDIW
+OvZRphws/W0lCB1eMq1D295Pt8+/+fQP3DNpiXxES3tpPn+/VIk6SoP8Xp7PwkEh
+phDjetf2TOfFUZWG6FpITgC5m+1JEqsJtjA=
+=Le1H
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub   2048R/C1D03D7A 2012-08-15
+      Key fingerprint = BC88 A75A F8CE FF74 022F  9D6C 7D50 C7E2 C1D0 3D7A
+uid                  German Grekhov <gg...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.18 (FreeBSD)
+
+mQENBFArJtUBCAClA1uy+U+wRJkzgqyQ/HlYZHniR/OGDjlu0043RiA1kQI/8EUK
+9sb/y+K8Um2D+HZw3pW++5wy4tz+o4i9HPvYZhS9dq8p8tthZmSHpg8p8PKrL1HQ
+GTsS5+atw3NB/6KWno5vDbY6UNtXjZ0gS5IYnccMksYeeb//pZJVwM1O36M5S/Gb
+iEm3YGBB4mUuRjDiAgbzyn+tI8vZovNb70gD1YPKRFhiE6Jn847o6+SH9GZflyHB
+/xPkOa3e/LRXBEuAPYgIySf1TroYyYYSebyqX2JA3joaIFuibvEaoXdr78aKaZ7S
+oboQd76gAlsMKcxAlYMMJXgvvApHYNIbSy7tABEBAAG0JEdlcm1hbiBHcmVraG92
+IDxnZ3Jla2hvdkBhcGFjaGUub3JnPokBOAQTAQIAIgUCUCsm1QIbAwYLCQgHAwIG
+FQgCCQoLBBYCAwECHgECF4AACgkQfVDH4sHQPXpgEQgAmi/AiYrZHaOsh81xEAfS
+9rmK2jp0eEtA4dmlhCEmlLKXGRY8ZQA/kk45qnY79ubjZT0xTILJPa6/UKNh8liH
+CtIN6GbnToBjB2VfO2oSMUydmXUtkhyE9J3EnJL3HaWaxquMNLw/ZKt5PXzgQlc0
+et3se5AOP5x4qCfyg0JS6EIuZRU4bWJ6LMhkgD4mwqRdQ7lq+s3GSCoUXjIxfO/f
+G0fB2ExGZJQk4fZ/8fBHZfe8lpAQgLJA5mRGxj7DdMsTDzN2SH+WNs2Y4/MXi4SL
+pCHWOdzVZDGOq8UaRqDLq1IUje6NHqltcAhJQBZ7fxlST35tHnNQvBMIvBZ366BN
+DLkBDQRQKybVAQgAoJfswqfYKqm+lFMavy9gA87kaNHU/E1kYSDXgetkgnuVDwG8
+jt4sU3SRc/OLgQVXVc12VFJRU36rKHuA0JkXrPgYi2LClIwnK7V+VqabtUc7OT2t
+Bd9pCEXk3J+6XKUPanRd9JkLR1liNj7pDmXEdc+Eaqqql+0KuGfxsHiVjP9kuoVV
+PcUWS5klcOIRI5ZUzkNDJXq7S6LN0TEHdtX/3R925wHBsspvtg4ca+mlJmwACs/o
+iOB3nwlScErDbKzkqcma2eMD0TCcrqlu99/Uv8ZdXBYHraHeBGtESJlZS72i5iog
+4y7yOw6QocW5h8B87efu/+6UoAQgY+2x6D50NQARAQABiQEfBBgBAgAJBQJQKybV
+AhsMAAoJEH1Qx+LB0D16+AoH/2++0UGjiT0QGXycQh3vLaMUdXjG3IihutBHtsBr
+CjOgeCSLAGpirYwUYqoE0GcTVnJ6POPDbsN/NcN+kza2miopYmuJrcF5rCk8Kevl
+o4GKdpj7AgYmO5BldyNcWOWYATNccPkvmPzqjBrx6KGNmGP9BWOie9G+sOMHfUPd
+dMtJDgkDPcyl4vyhN4tWGDFwo9TZLrKr/TNrUkrCcwtTFNw1Whiulq/Xp/0Ud2Dz
+TwlQyqiieZELEEltNSY8EVFBlH29Sg8WojddlVlC7l2mpGliSiVxZfAJmCTcrEcE
+T/534j+K1YDa5Wky8CcfE0NgYpUUtIxsbdfajuIo5Xu20ck=
+=I4K3
+-----END PGP PUBLIC KEY BLOCK-----
+


[49/50] [abbrv] openmeetings git commit: no JIRA: final URL to enter the room is fixed

Posted by so...@apache.org.
no JIRA: final URL to enter the room is fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/ba868aa5
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/ba868aa5
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/ba868aa5

Branch: refs/heads/master
Commit: ba868aa5ab1ce38a1d7550ac1f9e8047d91c50bf
Parents: bcfb736
Author: Maxim Solodovnik <so...@apache.org>
Authored: Mon Apr 24 09:02:01 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Mon Apr 24 09:02:01 2017 +0000

----------------------------------------------------------------------
 openmeetings-server/src/site/xdoc/RestAPISample.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ba868aa5/openmeetings-server/src/site/xdoc/RestAPISample.xml
----------------------------------------------------------------------
diff --git a/openmeetings-server/src/site/xdoc/RestAPISample.xml b/openmeetings-server/src/site/xdoc/RestAPISample.xml
index 12f6946..89710c8 100644
--- a/openmeetings-server/src/site/xdoc/RestAPISample.xml
+++ b/openmeetings-server/src/site/xdoc/RestAPISample.xml
@@ -132,7 +132,7 @@ $.ajax({
 					</table>
 				</li>
 				<li>If your request was successful you will get your hash as <b>message</b> (fa1f9381-bd03-42ae-9fd9-332b5f775a1b)</li>
-				<li>Now you can use following URL to enter the room: <tt>http://localhost:5080/openmeetings/swf?secureHash=fa1f9381-bd03-42ae-9fd9-332b5f775a1b&amp;language=1</tt></li>
+				<li>Now you can use following URL to enter the room: <tt>http://localhost:5080/openmeetings/hash?secure=fa1f9381-bd03-42ae-9fd9-332b5f775a1b&amp;language=1</tt></li>
 			</ul>
 		</section>
 	</body>


[32/50] [abbrv] openmeetings git commit: OPENMEETINGS-551 - The video frame closes for other participants when the participant with video leaves the room.

Posted by so...@apache.org.
OPENMEETINGS-551 - The video frame closes for other participants when the participant with video leaves the room.


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/d1c5df59
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/d1c5df59
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/d1c5df59

Branch: refs/heads/master
Commit: d1c5df59894794550cfb944e2276270972c2f174
Parents: e7bab5b
Author: Vasiliy Degtyarev <vd...@apache.org>
Authored: Tue Apr 18 04:21:31 2017 +0000
Committer: Vasiliy Degtyarev <vd...@apache.org>
Committed: Tue Apr 18 04:21:31 2017 +0000

----------------------------------------------------------------------
 .../main/java/org/apache/openmeetings/web/app/Application.java | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/d1c5df59/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index ac7cfa8..8d7fcec 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -60,6 +60,7 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.util.InitializationContainer;
 import org.apache.openmeetings.util.message.RoomMessage;
+import org.apache.openmeetings.util.message.TextRoomMessage;
 import org.apache.openmeetings.web.pages.AccessDeniedPage;
 import org.apache.openmeetings.web.pages.ActivatePage;
 import org.apache.openmeetings.web.pages.HashPage;
@@ -229,8 +230,10 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 
 	public static void exitRoom(Client c) {
 		Long roomId = c.getRoomId();
-		removeUserFromRoom(c);
 		if (roomId != null) {
+			if (hasVideo(c)){
+				sendRoom(new TextRoomMessage(c.getRoomId(), c.getUserId(), RoomMessage.Type.closeStream, c.getUid()));
+			}
 			sendRoom(new RoomMessage(roomId, c.getUserId(), RoomMessage.Type.roomExit));
 			getBean(ConferenceLogDao.class).add(
 					ConferenceLog.Type.roomLeave
@@ -238,6 +241,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 					, c.getRemoteAddress()
 					, "" + roomId);
 		}
+		removeUserFromRoom(c);
 	}
 
 	@Override


[16/50] [abbrv] openmeetings git commit: Changelog is updated to have changes for all versions

Posted by so...@apache.org.
Changelog is updated to have changes for all versions


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/d8a5a807
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/d8a5a807
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/d8a5a807

Branch: refs/heads/master
Commit: d8a5a8074a57d5d61b3aa367d136a895a6fc1b58
Parents: 5394af0
Author: Maxim Solodovnik <so...@apache.org>
Authored: Thu Apr 6 12:12:54 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Thu Apr 6 12:12:54 2017 +0000

----------------------------------------------------------------------
 CHANGELOG | 1478 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1478 insertions(+)
----------------------------------------------------------------------



[36/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] initial work on minimizing (broken)

Posted by so...@apache.org.
[OPENMEETINGS-551] initial work on minimizing (broken)


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/ac232ec4
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/ac232ec4
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/ac232ec4

Branch: refs/heads/master
Commit: ac232ec46e9e2fb68289fbcca68ba15d1d09c957
Parents: 1123594
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 19 03:26:57 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 19 03:26:57 2017 +0000

----------------------------------------------------------------------
 .../apache/openmeetings/web/room/RoomPanel.java |  12 +-
 .../web/room/jquery.dialogextend.js             | 329 +++++++++++++++++++
 .../web/room/jquery.dialogextend.min.js         |   3 +
 .../org/apache/openmeetings/web/room/room.js    |  45 ++-
 4 files changed, 366 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ac232ec4/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 8c2497f..9990345 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -78,7 +78,6 @@ import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
-import org.apache.wicket.request.resource.ResourceReference;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
@@ -170,11 +169,9 @@ public class RoomPanel extends BasePanel {
 					.put("height", c.getHeight());
 				target.appendJavaScript(String.format("VideoManager.play(%s);", json));
 			}
-			
 		}
-		
 	}
-	
+
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
@@ -542,14 +539,11 @@ public class RoomPanel extends BasePanel {
 		getMainPanel().getChat().roomExit(r, handler);
 	}
 
-	private static ResourceReference newResourceReference() {
-		return new JavaScriptResourceReference(RoomPanel.class, "room.js");
-	}
-
 	@Override
 	public void renderHead(IHeaderResponse response) {
 		super.renderHead(response);
-		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(newResourceReference())));
+		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(RoomPanel.class, "jquery.dialogextend.js"))));
+		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(RoomPanel.class, "room.js"))));
 		WebSession ws = WebSession.get();
 		if (!Strings.isEmpty(r.getRedirectURL()) && (ws.getSoapLogin() != null || ws.getInvitation() != null)) {
 			response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forScript(

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ac232ec4/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js
new file mode 100644
index 0000000..7a605e9
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.js
@@ -0,0 +1,329 @@
+/*
+ * Licensed MIT https://github.com/ROMB/jquery-dialogextend/blob/master/LICENSE.md
+ */
+(function() {
+  var $;
+
+  $ = jQuery;
+
+  $.widget("ui.dialogExtend", {
+    version: "2.0.4",
+    modes: {},
+    options: {
+      "closable": true,
+      "dblclick": false,
+      "titlebar": false,
+      "icons": {
+        "close": "ui-icon-closethick",
+        "restore": "ui-icon-newwin"
+      },
+      "load": null,
+      "beforeRestore": null,
+      "restore": null
+    },
+    _create: function() {
+      this._state = "normal";
+      if (!$(this.element[0]).data("ui-dialog")) {
+        $.error("jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted");
+      }
+      this._verifyOptions();
+      this._initStyles();
+      this._initButtons();
+      this._initTitleBar();
+      this._setState("normal");
+      this._on("load", function(e) {
+        return console.log("test", e);
+      });
+      return this._trigger("load");
+    },
+    _setState: function(state) {
+      $(this.element[0]).removeClass("ui-dialog-" + this._state).addClass("ui-dialog-" + state);
+      return this._state = state;
+    },
+    _verifyOptions: function() {
+      var name, _ref, _results;
+
+      if (this.options.dblclick && !(this.options.dblclick in this.modes)) {
+        $.error("jQuery.dialogExtend Error : Invalid <dblclick> value '" + this.options.dblclick + "'");
+        this.options.dblclick = false;
+      }
+      if (this.options.titlebar && ((_ref = this.options.titlebar) !== "none" && _ref !== "transparent")) {
+        $.error("jQuery.dialogExtend Error : Invalid <titlebar> value '" + this.options.titlebar + "'");
+        this.options.titlebar = false;
+      }
+      _results = [];
+      for (name in this.modes) {
+        if (this["_verifyOptions_" + name]) {
+          _results.push(this["_verifyOptions_" + name]());
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    },
+    _initStyles: function() {
+      var name, style, _results;
+
+      if (!$(".dialog-extend-css").length) {
+        style = '';
+        style += '<style class="dialog-extend-css" type="text/css">';
+        style += '.ui-dialog .ui-dialog-titlebar-buttonpane>a { float: right; }';
+        style += '.ui-dialog .ui-dialog-titlebar-restore { width: 19px; height: 18px; }';
+        style += '.ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }';
+        style += '.ui-dialog .ui-dialog-titlebar-restore:hover,';
+        style += '.ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }';
+        style += '.ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }';
+        style += '</style>';
+        $(style).appendTo("body");
+      }
+      _results = [];
+      for (name in this.modes) {
+        _results.push(this["_initStyles_" + name]());
+      }
+      return _results;
+    },
+    _initButtons: function() {
+      var buttonPane, mode, name, titlebar, _ref,
+        _this = this;
+
+      titlebar = $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar");
+      buttonPane = $('<div class="ui-dialog-titlebar-buttonpane"></div>').appendTo(titlebar);
+      buttonPane.css({
+        "position": "absolute",
+        "top": "50%",
+        "right": "0.3em",
+        "margin-top": "-10px",
+        "height": "18px"
+      });
+      titlebar.find(".ui-dialog-titlebar-close").css({
+        "position": "relative",
+        "float": "right",
+        "top": "auto",
+        "right": "auto",
+        "margin": 0
+      }).find(".ui-icon").removeClass("ui-icon-closethick").addClass(this.options.icons.close).end().appendTo(buttonPane).end();
+      buttonPane.append('<a class="ui-dialog-titlebar-restore ui-corner-all ui-state-default" href="#"><span class="ui-icon ' + this.options.icons.restore + '" title="restore">restore</span></a>').find('.ui-dialog-titlebar-restore').attr("role", "button").mouseover(function() {
+        return $(this).addClass("ui-state-hover");
+      }).mouseout(function() {
+        return $(this).removeClass("ui-state-hover");
+      }).focus(function() {
+        return $(this).addClass("ui-state-focus");
+      }).blur(function() {
+        return $(this).removeClass("ui-state-focus");
+      }).end().find(".ui-dialog-titlebar-close").toggle(this.options.closable).end().find(".ui-dialog-titlebar-restore").hide().click(function(e) {
+        e.preventDefault();
+        return _this.restore();
+      }).end();
+      _ref = this.modes;
+      for (name in _ref) {
+        mode = _ref[name];
+        this._initModuleButton(name, mode);
+      }
+      return titlebar.dblclick(function(evt) {
+        if (_this.options.dblclick) {
+          if (_this._state !== "normal") {
+            return _this.restore();
+          } else {
+            return _this[_this.options.dblclick]();
+          }
+        }
+      }).select(function() {
+        return false;
+      });
+    },
+    _initModuleButton: function(name, mode) {
+      var buttonPane,
+        _this = this;
+
+      buttonPane = $(this.element[0]).dialog("widget").find('.ui-dialog-titlebar-buttonpane');
+      return buttonPane.append('<a class="ui-dialog-titlebar-' + name + ' ui-corner-all ui-state-default" href="#" title="' + name + '"><span class="ui-icon ' + this.options.icons[name] + '">' + name + '</span></a>').find(".ui-dialog-titlebar-" + name).attr("role", "button").mouseover(function() {
+        return $(this).addClass("ui-state-hover");
+      }).mouseout(function() {
+        return $(this).removeClass("ui-state-hover");
+      }).focus(function() {
+        return $(this).addClass("ui-state-focus");
+      }).blur(function() {
+        return $(this).removeClass("ui-state-focus");
+      }).end().find(".ui-dialog-titlebar-" + name).toggle(this.options[mode.option]).click(function(e) {
+        e.preventDefault();
+        return _this[name]();
+      }).end();
+    },
+    _initTitleBar: function() {
+      var handle;
+
+      switch (this.options.titlebar) {
+        case false:
+          return 0;
+        case "none":
+          if ($(this.element[0]).dialog("option", "draggable")) {
+            handle = $("<div />").addClass("ui-dialog-draggable-handle").css("cursor", "move").height(5);
+            $(this.element[0]).dialog("widget").prepend(handle).draggable("option", "handle", handle);
+          }
+          return $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").find(".ui-dialog-title").html("&nbsp;").end().css({
+            "background-color": "transparent",
+            "background-image": "none",
+            "border": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+            "z-index": 9999
+          }).end();
+        case "transparent":
+          return $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css({
+            "background-color": "transparent",
+            "background-image": "none",
+            "border": 0
+          });
+        default:
+          return $.error("jQuery.dialogExtend Error : Invalid <titlebar> value '" + this.options.titlebar + "'");
+      }
+    },
+    state: function() {
+      return this._state;
+    },
+    restore: function() {
+      this._trigger("beforeRestore");
+      this._restore();
+      this._toggleButtons();
+      return this._trigger("restore");
+    },
+    _restore: function() {
+      if (this._state !== "normal") {
+        this["_restore_" + this._state]();
+        this._setState("normal");
+        return $(this.element[0]).dialog("widget").focus();
+      }
+    },
+    _saveSnapshot: function() {
+      if (this._state === "normal") {
+        this.original_config_resizable = $(this.element[0]).dialog("option", "resizable");
+        this.original_config_draggable = $(this.element[0]).dialog("option", "draggable");
+        this.original_size_height = $(this.element[0]).dialog("widget").outerHeight();
+        this.original_size_width = $(this.element[0]).dialog("option", "width");
+        this.original_size_maxHeight = $(this.element[0]).dialog("option", "maxHeight");
+        this.original_position_mode = $(this.element[0]).dialog("widget").css("position");
+        this.original_position_left = $(this.element[0]).dialog("widget").offset().left - $('body').scrollLeft();
+        this.original_position_top = $(this.element[0]).dialog("widget").offset().top - $('body').scrollTop();
+        return this.original_titlebar_wrap = $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css("white-space");
+      }
+    },
+    _loadSnapshot: function() {
+      return {
+        "config": {
+          "resizable": this.original_config_resizable,
+          "draggable": this.original_config_draggable
+        },
+        "size": {
+          "height": this.original_size_height,
+          "width": this.original_size_width,
+          "maxHeight": this.original_size_maxHeight
+        },
+        "position": {
+          "mode": this.original_position_mode,
+          "left": this.original_position_left,
+          "top": this.original_position_top
+        },
+        "titlebar": {
+          "wrap": this.original_titlebar_wrap
+        }
+      };
+    },
+    _toggleButtons: function(newstate) {
+      var mode, name, state, _ref, _ref1, _results;
+
+      state = newstate || this._state;
+      $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").toggle(state !== "normal").css({
+        "right": "1.4em"
+      }).end();
+      _ref = this.modes;
+      for (name in _ref) {
+        mode = _ref[name];
+        $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-" + name).toggle(state !== mode.state && this.options[mode.option]);
+      }
+      _ref1 = this.modes;
+      _results = [];
+      for (name in _ref1) {
+        mode = _ref1[name];
+        if (mode.state === state) {
+          _results.push($(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").insertAfter($(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-" + name)).end());
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    }
+  });
+
+}).call(this);
+
+(function() {
+  var $;
+
+  $ = jQuery;
+
+  $.extend(true, $.ui.dialogExtend.prototype, {
+    modes: {
+      "collapse": {
+        option: "collapsable",
+        state: "collapsed"
+      }
+    },
+    options: {
+      "collapsable": false,
+      "icons": {
+        "collapse": "ui-icon-triangle-1-s"
+      },
+      "beforeCollapse": null,
+      "collapse": null
+    },
+    collapse: function() {
+      var newHeight, pos;
+
+      newHeight = $(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height() + 15;
+      this._trigger("beforeCollapse");
+      if (this._state !== "normal") {
+        this._restore();
+      }
+      this._saveSnapshot();
+      pos = $(this.element[0]).dialog("widget").position();
+      $(this.element[0]).dialog("option", {
+        "resizable": false,
+        "height": newHeight,
+        "maxHeight": newHeight,
+        "position": [pos.left - $(document).scrollLeft(), pos.top - $(document).scrollTop()]
+      }).on('dialogclose', this._collapse_restore).hide().dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space", "nowrap").end().find(".ui-dialog-content");
+      this._setState("collapsed");
+      this._toggleButtons();
+      return this._trigger("collapse");
+    },
+    _restore_collapsed: function() {
+      var original;
+
+      original = this._loadSnapshot();
+      return $(this.element[0]).show().dialog("widget").find(".ui-dialog-buttonpane:hidden").show().end().find(".ui-dialog-titlebar").css("white-space", original.titlebar.wrap).end().find(".ui-dialog-content").dialog("option", {
+        "resizable": original.config.resizable,
+        "height": original.size.height,
+        "maxHeight": original.size.maxHeight
+      }).off('dialogclose', this._collapse_restore);
+    },
+    _initStyles_collapse: function() {
+      var style;
+
+      if (!$(".dialog-extend-collapse-css").length) {
+        style = '';
+        style += '<style class="dialog-extend-collapse-css" type="text/css">';
+        style += '.ui-dialog .ui-dialog-titlebar-collapse { width: 19px; height: 18px; }';
+        style += '.ui-dialog .ui-dialog-titlebar-collapse span { display: block; margin: 1px; }';
+        style += '.ui-dialog .ui-dialog-titlebar-collapse:hover,';
+        style += '.ui-dialog .ui-dialog-titlebar-collapse:focus { padding: 0; }';
+        style += '</style>';
+        return $(style).appendTo("body");
+      }
+    },
+    _collapse_restore: function() {
+      return $(this).dialogExtend("restore");
+    }
+  });
+
+}).call(this);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ac232ec4/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
new file mode 100644
index 0000000..7aaae95
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/jquery.dialogextend.min.js
@@ -0,0 +1,3 @@
+/* Licensed MIT */
+/*! jquery-dialogextend 2.0.4 2014-07-08 */
+(function(){var i;i=jQuery,i.widget("ui.dialogExtend",{version:"2.0.4",modes:{},options:{closable:!0,dblclick:!1,titlebar:!1,icons:{close:"ui-icon-closethick",restore:"ui-icon-newwin"},load:null,beforeRestore:null,restore:null},_create:function(){return this._state="normal",i(this.element[0]).data("ui-dialog")||i.error("jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted"),this._verifyOptions(),this._initStyles(),this._initButtons(),this._initTitleBar(),this._setState("normal"),this._on("load",function(i){return console.log("test",i)}),this._trigger("load")},_setState:function(t){return i(this.element[0]).removeClass("ui-dialog-"+this._state).addClass("ui-dialog-"+t),this._state=t},_verifyOptions:function(){var t,e,o;!this.options.dblclick||this.options.dblclick in this.modes||(i.error("jQuery.dialogExtend Error : Invalid <dblclick> value '"+this.options.dblclick+"'"),this.options.dblclick=!1),this.options.titlebar&&"none"!==(e=this.options.titlebar)&&"transparent"
 !==e&&(i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'"),this.options.titlebar=!1),o=[];for(t in this.modes)this["_verifyOptions_"+t]?o.push(this["_verifyOptions_"+t]()):o.push(void 0);return o},_initStyles:function(){var t,e,o;i(".dialog-extend-css").length||(e="",e+='<style class="dialog-extend-css" type="text/css">',e+=".ui-dialog .ui-dialog-titlebar-buttonpane>a { float: right; }",e+=".ui-dialog .ui-dialog-titlebar-restore { width: 19px; height: 18px; }",e+=".ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }",e+=".ui-dialog .ui-dialog-titlebar-restore:hover,",e+=".ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }",e+=".ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }",e+="</style>",i(e).appendTo("body")),o=[];for(t in this.modes)o.push(this["_initStyles_"+t]());return o},_initButtons:function(){var t,e,o,n,a,l=this;n=i(this.element[0]).dialog("widget").find(".ui-dialog-title
 bar"),t=i('<div class="ui-dialog-titlebar-buttonpane"></div>').appendTo(n),t.css({position:"absolute",top:"50%",right:"0.3em","margin-top":"-10px",height:"18px"}),n.find(".ui-dialog-titlebar-close").css({position:"relative","float":"right",top:"auto",right:"auto",margin:0}).find(".ui-icon").removeClass("ui-icon-closethick").addClass(this.options.icons.close).end().appendTo(t).end(),t.append('<a class="ui-dialog-titlebar-restore ui-corner-all ui-state-default" href="#"><span class="ui-icon '+this.options.icons.restore+'" title="restore">restore</span></a>').find(".ui-dialog-titlebar-restore").attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-close").toggle(this.options.closable).end().find(".ui-dialog-titlebar-restore").hide().c
 lick(function(i){return i.preventDefault(),l.restore()}).end(),a=this.modes;for(o in a)e=a[o],this._initModuleButton(o,e);return n.dblclick(function(){return l.options.dblclick?"normal"!==l._state?l.restore():l[l.options.dblclick]():void 0}).select(function(){return!1})},_initModuleButton:function(t,e){var o,n=this;return o=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-buttonpane"),o.append('<a class="ui-dialog-titlebar-'+t+' ui-corner-all ui-state-default" href="#" title="'+t+'"><span class="ui-icon '+this.options.icons[t]+'">'+t+"</span></a>").find(".ui-dialog-titlebar-"+t).attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-"+t).toggle(this.options[e.option]).click(function(i){return i.preventDefault(),n[t]()})
 .end()},_initTitleBar:function(){var t;switch(this.options.titlebar){case!1:return 0;case"none":return i(this.element[0]).dialog("option","draggable")&&(t=i("<div />").addClass("ui-dialog-draggable-handle").css("cursor","move").height(5),i(this.element[0]).dialog("widget").prepend(t).draggable("option","handle",t)),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").find(".ui-dialog-title").html("&nbsp;").end().css({"background-color":"transparent","background-image":"none",border:0,position:"absolute",right:0,top:0,"z-index":9999}).end();case"transparent":return i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css({"background-color":"transparent","background-image":"none",border:0});default:return i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'")}},state:function(){return this._state},restore:function(){return this._trigger("beforeRestore"),this._restore(),this._toggleButtons(),this._trigger("restore")},_restore:
 function(){return"normal"!==this._state?(this["_restore_"+this._state](),this._setState("normal"),i(this.element[0]).dialog("widget").focus()):void 0},_saveSnapshot:function(){return"normal"===this._state?(this.original_config_resizable=i(this.element[0]).dialog("option","resizable"),this.original_config_draggable=i(this.element[0]).dialog("option","draggable"),this.original_size_height=i(this.element[0]).dialog("widget").outerHeight(),this.original_size_width=i(this.element[0]).dialog("option","width"),this.original_size_maxHeight=i(this.element[0]).dialog("option","maxHeight"),this.original_position_mode=i(this.element[0]).dialog("widget").css("position"),this.original_position_left=i(this.element[0]).dialog("widget").offset().left-i("body").scrollLeft(),this.original_position_top=i(this.element[0]).dialog("widget").offset().top-i("body").scrollTop(),this.original_titlebar_wrap=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css("white-space")):void 0},_loadSnapsho
 t:function(){return{config:{resizable:this.original_config_resizable,draggable:this.original_config_draggable},size:{height:this.original_size_height,width:this.original_size_width,maxHeight:this.original_size_maxHeight},position:{mode:this.original_position_mode,left:this.original_position_left,top:this.original_position_top},titlebar:{wrap:this.original_titlebar_wrap}}},_toggleButtons:function(t){var e,o,n,a,l,s;n=t||this._state,i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").toggle("normal"!==n).css({right:"1.4em"}).end(),a=this.modes;for(o in a)e=a[o],i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o).toggle(n!==e.state&&this.options[e.option]);l=this.modes,s=[];for(o in l)e=l[o],e.state===n?s.push(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").insertAfter(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o)).end()):s.push(void 0);return s}})}).call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dia
 logExtend.prototype,{modes:{collapse:{option:"collapsable",state:"collapsed"}},options:{collapsable:!1,icons:{collapse:"ui-icon-triangle-1-s"},beforeCollapse:null,collapse:null},collapse:function(){var t,e;return t=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height()+15,this._trigger("beforeCollapse"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),e=i(this.element[0]).dialog("widget").position(),i(this.element[0]).dialog("option",{resizable:!1,height:t,maxHeight:t,position:[e.left-i(document).scrollLeft(),e.top-i(document).scrollTop()]}).on("dialogclose",this._collapse_restore).hide().dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space","nowrap").end().find(".ui-dialog-content"),this._setState("collapsed"),this._toggleButtons(),this._trigger("collapse")},_restore_collapsed:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).show().dialog("widget").find(".ui-dialog-buttonpane:
 hidden").show().end().find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,height:t.size.height,maxHeight:t.size.maxHeight}).off("dialogclose",this._collapse_restore)},_initStyles_collapse:function(){var t;return i(".dialog-extend-collapse-css").length?void 0:(t="",t+='<style class="dialog-extend-collapse-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-collapse { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse:hover,",t+=".ui-dialog .ui-dialog-titlebar-collapse:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_collapse_restore:function(){return i(this).dialogExtend("restore")}})}.call(this);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ac232ec4/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index 2b9e9e4..c85190e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -17,39 +17,57 @@
  * under the License.
  */
 var Video = (function() {
-	var self = {}, c, box, v, vc, t, swf;
+	var self = {}, c, box, v, vc, t, swf, size;
 
 	function _getName() {
 		return c.user.firstName + ' ' + c.user.lastName;
 	}
-	function _resetSize() {
-		v.dialog("option", "width", c.width).dialog("option", "height", t.height() + c.height + 2);
-		vc.width(c.width).height(c.height);
-		swf.attr('width', c.width).attr('height', c.height);
+	function _resetSize(_w, _h) {
+		var w = _w || size.width, h = _h || size.height;
+		_setSize(w, h);
+	}
+	function _setSize(w, h) {
+		v.dialog("option", "width", w).dialog("option", "height", t.height() + h + 2);
+		vc.width(w).height(h);
+		swf.attr('width', w).attr('height', h);
 	}
 	function _init(_box, _c) {
 		c = _c;
 		box = _box;
+		size = {width: c.width, height: c.height};
 		var _id = "video" + c.uid, name = _getName()
-			, w = c.self ? Math.max(300, c.width) : c.width
-			, h = c.self ? Math.max(200, c.height) : c.height;
+			, _w = c.self ? Math.max(300, c.width) : c.width
+			, _h = c.self ? Math.max(200, c.height) : c.height;
 		box.append($('#user-video').clone().attr('id', _id).attr('title', name).data(self));
 		v = $('#' + _id);
 		v.dialog({
 			classes: {
 				'ui-dialog': 'ui-corner-all video user-video'
-				, 'ui-dialog-titlebar': 'ui-corner-all no-close'
 			}
-			, width: w
+			, width: _w
 			, minWidth: 40
 			, minHeight: 50
 			, autoOpen: true
 			, modal: false
-			//resizeStop
+			, resizeStop: function(event, ui) {
+				var i = 0;
+			}
+		}).dialogExtend({
+			icons: {
+				'collapse': 'ui-icon-minus'
+			}
+			, closable: false
+			, collapsable: true
+			, dblclick: "collapse"
+			, restore : function(evt, dlg) {
+				var w = c.self ? Math.max(300, size.width) : size.width
+					, h = c.self ? Math.max(200, size.height) : size.height;
+				_setSize(w, h);
+			}
 		});
 		t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
 		vc = v.find('.video');
-		vc.width(w).height(h);
+		vc.width(_w).height(_h);
 		//broadcast
 		var o = VideoManager.getOptions();
 		if (c.self) {
@@ -65,7 +83,7 @@ var Video = (function() {
 		o.sid = c.sid;
 		o.broadcastId = c.broadcastId;
 		swf = initVideo(vc, _id + '-swf', o);
-		swf.attr('width', w).attr('height', h);
+		swf.attr('width', _w).attr('height', _h);
 	}
 	function _update(_c) {
 		// TODO check, update video
@@ -106,8 +124,7 @@ var VideoManager = (function() {
 		Video().init(box, c);
 	}
 	function _close(uid) {
-		var _id = _getVid(uid)
-			, v = $('#' + _id);
+		var _id = _getVid(uid), v = $('#' + _id);
 		if (v.length == 1) {
 			v.remove();
 		}


[19/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1624] file upload should work in IE11

Posted by so...@apache.org.
[OPENMEETINGS-1624] file upload should work in IE11


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/b63f9dde
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/b63f9dde
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/b63f9dde

Branch: refs/heads/master
Commit: b63f9dde6a13a6b899cb84d3c611670556b6f8cc
Parents: 35544aa
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sat Apr 8 10:25:17 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sat Apr 8 10:25:17 2017 +0000

----------------------------------------------------------------------
 .../apache/openmeetings/web/room/SwfPanel.html  |  7 +--
 .../apache/openmeetings/web/room/SwfPanel.java  | 61 +++++++++++++-------
 .../openmeetings/web/room/swf-functions.js      |  2 +-
 .../apache/openmeetings/web/user/chat/chat.js   | 11 +++-
 4 files changed, 53 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b63f9dde/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.html
index 9addd3b..fc318ca 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.html
@@ -7,16 +7,16 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-  
+
       http://www.apache.org/licenses/LICENSE-2.0
-    	  
+
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-  
+
 -->
 <html xmlns:wicket="http://wicket.apache.org">
 <wicket:head>
@@ -44,6 +44,5 @@
 		<img src="images/ajax-loader.gif" />
 	</div>
 	<noscript>Please enable JavaScript in order to use this application.</noscript>
-	<script type="text/javascript" wicket:id="init"></script>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b63f9dde/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
index bff4cda..255040c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
@@ -21,11 +21,15 @@ package org.apache.openmeetings.web.room;
 import static org.apache.wicket.RuntimeConfigurationType.DEVELOPMENT;
 
 import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.BasePanel;
+import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
-import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.protocol.http.ClientProperties;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
@@ -41,13 +45,42 @@ public class SwfPanel extends BasePanel {
 	public static final String SWF = "swf";
 	public static final String SWF_TYPE_NETWORK = "network";
 	public static final String SWF_TYPE_SETTINGS = "settings";
+	private final PageParameters pp;
+	private final AbstractDefaultAjaxBehavior panelLoaded = new AbstractDefaultAjaxBehavior() {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		protected void respond(AjaxRequestTarget target) {
+			PageParameters spp = new PageParameters(pp);
+			target.appendJavaScript(getInitFunction(spp));
+		}
+	};
 
 	public SwfPanel(String id) {
 		this(id, new PageParameters());
 	}
 
-	public String getInitFunction() {
-		return getInitFunction(new PageParameters());
+	public SwfPanel(String id, PageParameters pp) {
+		super(id);
+		this.pp = pp;
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
+		add(panelLoaded);
+	}
+
+	private static ResourceReference newResourceReference() {
+		return new JavaScriptResourceReference(SwfPanel.class, "swf-functions.js");
+	}
+
+	@Override
+	public void renderHead(IHeaderResponse response) {
+		super.renderHead(response);
+		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(newResourceReference())));
+		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forUrl("js/openmeetings_functions.js")));
+		response.render(OnDomReadyHeaderItem.forScript(panelLoaded.getCallbackScript()));
 	}
 
 	public String getInitFunction(PageParameters pp) {
@@ -77,8 +110,10 @@ public class SwfPanel extends BasePanel {
 						, "775", "452", "767", "764", "765", "918", "54", "761", "762", "144", "203", "642"
 						, "save.success");
 			}
-			initStr = String.format("var labels = %s; initSwf(%s);", lbls
-					, new JSONObject().put("src", swf + new PageParametersEncoder().encodePageParameters(pp)).toString());
+			JSONObject options = new JSONObject().put("src", swf + new PageParametersEncoder().encodePageParameters(pp));
+			ClientProperties cp = WebSession.get().getClientInfo().getProperties();
+			options.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct");
+			initStr = String.format("var labels = %s; initSwf(%s);", lbls, options.toString());
 		}
 		return initStr;
 	}
@@ -102,20 +137,4 @@ public class SwfPanel extends BasePanel {
 		}
 		return arr.toString();
 	}
-
-	public SwfPanel(String id, PageParameters pp) {
-		super(id);
-		add(new Label("init", getInitFunction(pp)).setEscapeModelStrings(false));
-	}
-
-	private static ResourceReference newResourceReference() {
-		return new JavaScriptResourceReference(SwfPanel.class, "swf-functions.js");
-	}
-
-	@Override
-	public void renderHead(IHeaderResponse response) {
-		super.renderHead(response);
-		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(newResourceReference())));
-		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forUrl("js/openmeetings_functions.js")));
-	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b63f9dde/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
index aa84eba..5ecc512 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
@@ -31,7 +31,7 @@ function initSwf(_options) {
 		.attr('quality', 'high')
 		.attr('bgcolor', options.bgcolor)
 		.attr('src', "public/" + options.src)
-		.attr('wmode', 'direct')
+		.attr('wmode', options.wmode)
 		.attr('allowfullscreen', true)
 		.attr('width', options.width).attr('height', options.height)
 		.attr('id', 'lzapp')

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b63f9dde/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js
index 570d33e..ca6548d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js
@@ -33,9 +33,16 @@ var Chat = function() {
 		, emoticon = new CSSEmoticon()
 		, typingTimer
 		, doneTypingInterval = 5000 //time in ms, 5 second for example
-		, audio = new Audio('./public/chat_message.mp3');
+		, audio
 		;
-
+	try {
+		audio = new Audio('./public/chat_message.mp3');
+	} catch (e) {
+		//not implemented in IE
+		audio = {
+			play: function() {}
+		};
+	}
 	function doneTyping () {
 		typingTimer = null;
 		chatActivity('typing_stop', $('.room.box').data('room-id'));


[09/50] [abbrv] openmeetings git commit: [OPENMEETINGS-980] wicket/wicketstuff versions are changed to M5

Posted by so...@apache.org.
[OPENMEETINGS-980] wicket/wicketstuff versions are changed to M5


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/0a4bb368
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/0a4bb368
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/0a4bb368

Branch: refs/heads/master
Commit: 0a4bb368c220d123f4937d15906f833a5e8bbb02
Parents: d006c54
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 2 15:07:52 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 2 15:07:52 2017 +0000

----------------------------------------------------------------------
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/0a4bb368/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 535d743..ce0e527 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,9 +40,9 @@
 		<maven.javadoc.version>2.10.3</maven.javadoc.version>
 		<maven.surefire.version>2.19.1</maven.surefire.version>
 		<maven-site.version>3.3</maven-site.version>
-		<wicket.version>8.0.0-SNAPSHOT</wicket.version>
+		<wicket.version>8.0.0-M5</wicket.version>
 		<wicketju.version>8.0.0-M5</wicketju.version>
-		<wickets.version>8.0.0-SNAPSHOT</wickets.version>
+		<wickets.version>8.0.0-M5</wickets.version>
 		<red5-server.version>1.0.9-M6</red5-server.version>
 		<red5-client.version>1.0.9-M6</red5-client.version>
 		<spring.version>4.3.6.RELEASE</spring.version>


[39/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1632] screen-sharing download is fixed

Posted by so...@apache.org.
[OPENMEETINGS-1632] screen-sharing download is fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/91866ad2
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/91866ad2
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/91866ad2

Branch: refs/heads/master
Commit: 91866ad20efab6ce634d004c6dacf9c8a12cb091
Parents: 7b108d9
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 19 09:24:14 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 19 09:24:14 2017 +0000

----------------------------------------------------------------------
 .../org/apache/openmeetings/web/room/menu/StartSharingButton.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/91866ad2/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
index 1250eb5..111dc66 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
@@ -72,12 +72,12 @@ public class StartSharingButton extends OmButton {
 			private static final long serialVersionUID = 1L;
 
 			{
-				setFileName(String.format("public_%s.jnlp", StartSharingButton.this.c.getRoomId()));
 				setCacheDuration(NONE);
 			}
 
 			@Override
 			protected IResourceStream getResourceStream(Attributes attributes) {
+				setFileName(String.format("public_%s.jnlp", StartSharingButton.this.c.getRoomId()));
 				StringResourceStream srs = new StringResourceStream(app, "application/x-java-jnlp-file");
 				srs.setCharset(UTF_8);
 				return srs;


[10/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] missing WB icons are added

Posted by so...@apache.org.
[OPENMEETINGS-551] missing WB icons are added


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/821bc0ad
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/821bc0ad
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/821bc0ad

Branch: refs/heads/master
Commit: 821bc0adf6874e9a8f2216795abaf6a72aa59bf2
Parents: 0a4bb36
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 2 17:30:01 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 2 17:30:01 2017 +0000

----------------------------------------------------------------------
 .../apache/openmeetings/web/room/wb/WbPanel.html   |   8 ++++++++
 .../src/main/webapp/css/images/arrow_undo.png      | Bin 0 -> 1579 bytes
 .../src/main/webapp/css/images/cancel.png          | Bin 0 -> 1713 bytes
 .../src/main/webapp/css/images/file_save_as.png    | Bin 0 -> 2710 bytes
 .../src/main/webapp/css/images/page_delete.png     | Bin 0 -> 1335 bytes
 openmeetings-web/src/main/webapp/css/room.css      |  16 ++++++++++++++--
 6 files changed, 22 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/821bc0ad/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
index 7857c41..92963b6 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
@@ -58,6 +58,14 @@
 		</div>
 		<div id="wb-tools" class="tools ui-state-active vertical clear" style="position: absolute; top: 20px; right: 0px;">
 			<div class="bumper"></div>
+			<div wicket:message="title:62" class="ui-widget-header clickable om-icon big clear-all"></div>
+<!-- clear-all confirnmation: 1340 -->
+			<div wicket:message="title:1005" class="ui-widget-header clickable om-icon big clear-slide"></div>
+<!-- clear-slide confirmation 1359 -->
+			<div wicket:message="title:197" class="ui-widget-header clickable om-icon big save"></div>
+<!-- save-as filename -->
+			<div wicket:message="title:70" class="ui-widget-header clickable om-icon big undo"></div>
+
 			<div wicket:message="title:72" class="ui-widget-header clickable om-icon big pointer"></div>
 			<div wicket:message="title:557" class="ui-widget-header clickable om-icon big apointer"></div>
 			<div wicket:message="title:73" class="ui-widget-header clickable om-icon big text"></div>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/821bc0ad/openmeetings-web/src/main/webapp/css/images/arrow_undo.png
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/images/arrow_undo.png b/openmeetings-web/src/main/webapp/css/images/arrow_undo.png
new file mode 100644
index 0000000..be4f8e9
Binary files /dev/null and b/openmeetings-web/src/main/webapp/css/images/arrow_undo.png differ

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/821bc0ad/openmeetings-web/src/main/webapp/css/images/cancel.png
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/images/cancel.png b/openmeetings-web/src/main/webapp/css/images/cancel.png
new file mode 100644
index 0000000..1b20ae0
Binary files /dev/null and b/openmeetings-web/src/main/webapp/css/images/cancel.png differ

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/821bc0ad/openmeetings-web/src/main/webapp/css/images/file_save_as.png
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/images/file_save_as.png b/openmeetings-web/src/main/webapp/css/images/file_save_as.png
new file mode 100644
index 0000000..4bb38e9
Binary files /dev/null and b/openmeetings-web/src/main/webapp/css/images/file_save_as.png differ

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/821bc0ad/openmeetings-web/src/main/webapp/css/images/page_delete.png
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/images/page_delete.png b/openmeetings-web/src/main/webapp/css/images/page_delete.png
new file mode 100644
index 0000000..c7c33dd
Binary files /dev/null and b/openmeetings-web/src/main/webapp/css/images/page_delete.png differ

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/821bc0ad/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index 96d9412..cfbe13c 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -137,14 +137,14 @@
 }
 .room.wb.area .tools.vertical {
 	width: 38px;
-	height: 420px;
+	height: 563px;
 }
 .room.wb.area .tools.readonly.vertical {
 	width: 38px;
 	height: 60px;
 }
 .room.wb.area .tools.horisontal {
-	width: 420px;
+	width: 563px;
 	height: 38px;
 }
 .room.wb.area .tools.readonly.horisontal {
@@ -185,6 +185,18 @@
 .room.wb.area .tools .om-icon.big.arrow {
 	background-image: url(images/arrow.png);
 }
+.room.wb.area .tools .om-icon.big.clear-all {
+	background-image: url(images/cancel.png);
+}
+.room.wb.area .tools .om-icon.big.clear-slide {
+	background-image: url(images/page_delete.png);
+}
+.room.wb.area .tools .om-icon.big.save {
+	background-image: url(images/file_save_as.png);
+}
+.room.wb.area .tools .om-icon.big.undo {
+	background-image: url(images/arrow_undo.png);
+}
 .room.wb.area .om-icon.big.next {
 	background-image: url(images/next.png);
 }


[20/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] basic work on settings dialog

Posted by so...@apache.org.
[OPENMEETINGS-551] basic work on settings dialog


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/5d85a641
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/5d85a641
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/5d85a641

Branch: refs/heads/master
Commit: 5d85a6417b89852065d8a6583de16a2681910e89
Parents: b63f9dd
Author: Maxim Solodovnik <so...@apache.org>
Authored: Mon Apr 10 16:58:56 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Mon Apr 10 16:58:56 2017 +0000

----------------------------------------------------------------------
 openmeetings-flash/openlaszlo.xml               |  26 +-
 openmeetings-flash/src/main/flex/main.mxml      | 399 +++++--------------
 .../apache/openmeetings/web/room/RoomPanel.java |   7 +-
 .../org/apache/openmeetings/web/room/room.js    | 113 ++++--
 .../web/room/sidebar/RoomSidebar.html           |  11 +-
 openmeetings-web/src/main/webapp/css/room.css   |   7 +
 .../main/webapp/js/openmeetings_functions.js    |  64 ---
 7 files changed, 200 insertions(+), 427 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5d85a641/openmeetings-flash/openlaszlo.xml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/openlaszlo.xml b/openmeetings-flash/openlaszlo.xml
index ee8eacc..1cffc9a 100644
--- a/openmeetings-flash/openlaszlo.xml
+++ b/openmeetings-flash/openlaszlo.xml
@@ -7,9 +7,9 @@
   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
@@ -19,10 +19,10 @@
  -->
 <!DOCTYPE project>
 <project name="openmeetings" basedir="./" default="client.only"
-	xmlns="antlib:org.apache.tools.ant"
-	xmlns:rat="antlib:org.apache.rat.anttasks"
-	xmlns:ivy="antlib:org.apache.ivy.ant"
-	xmlns:artifact="antlib:org.apache.maven.artifact.ant"
+		xmlns="antlib:org.apache.tools.ant"
+		xmlns:rat="antlib:org.apache.rat.anttasks"
+		xmlns:ivy="antlib:org.apache.ivy.ant"
+		xmlns:artifact="antlib:org.apache.maven.artifact.ant"
 	>
 	<property name="laszlo46.home" value="${openlaszlo}/openlaszlo46" />
 	<!-- LPS Properties -->
@@ -32,7 +32,7 @@
 	<path id="laszlo46.lib">
 		<fileset dir="${laszlo46.home}/WEB-INF/lib" includes="*.jar" />
 	</path>
-	
+
 	<target name="client.only" depends="compile.flex, compile.laszlo.networktesting" unless="client-already-built">
 		<property name="client-already-built" value="true"/>
 	</target>
@@ -77,19 +77,19 @@
 	<condition property="isWindows">
 		<os family="windows" />
 	</condition>
-	
+
 	<condition property="isUnix">
 		<os family="unix" />
 	</condition>
-	
+
 	<target name="if_windows" if="isWindows">
 		<property name="mxmlc_bin" value="mxmlc.bat" />
 	</target>
-	
+
 	<target name="if_unix" if="isUnix">
 		<property name="mxmlc_bin" value="mxmlc" />
 	</target>
-	
+
 	<target name="-compile.flex" description="compile flash application" depends="if_windows, if_unix">
 		<exec dir="${flex.src.dir}" executable="${laszlo46.home}/WEB-INF/flexsdk/4.15.0/bin/${mxmlc_bin}">
 			<arg value="main.mxml"/>
@@ -97,11 +97,11 @@
 			<env key="PLAYERGLOBAL_HOME" value="${laszlo46.home}/WEB-INF/flexsdk/4.15.0/frameworks/libs/player"/>
 		</exec>
 	</target>
-	
+
 	<target name="compile.flex" depends="compile.flex.debug">
 		<antcall target="-compile.flex" inheritAll="true" inheritRefs="true"/>
 	</target>
-	
+
 	<target name="compile.flex.debug">
 		<!--antcall target="-compile.flex" inheritAll="true" inheritRefs="true"/-->
 	</target>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5d85a641/openmeetings-flash/src/main/flex/main.mxml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/main.mxml b/openmeetings-flash/src/main/flex/main.mxml
index 9287291..ec3792c 100644
--- a/openmeetings-flash/src/main/flex/main.mxml
+++ b/openmeetings-flash/src/main/flex/main.mxml
@@ -20,25 +20,18 @@
 -->
 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
 		xmlns:s="library://ns.adobe.com/flex/spark"
-		xmlns:mx="library://ns.adobe.com/flex/mx" width="570" height="900" pageTitle="Openmeetings"
+		xmlns:mx="library://ns.adobe.com/flex/mx"
+		width="570" height="900" pageTitle="Openmeetings"
 		preinitialize="init()" fontSize="12" applicationComplete="appInit()">
 	<fx:Declarations>
 		<!-- Place non-visual elements (e.g., services, value objects) here -->
 		<mx:TraceTarget/>
 	</fx:Declarations>
 	<fx:Script><![CDATA[
-		import mx.collections.ArrayCollection;
 		import mx.core.FlexGlobals;
+
 		import org.apache.openmeetings.OmVideo;
 
-		private static const MODE_N:String = "n";
-		private static const MODE_A:String = "a";
-		private static const MODE_V:String = "v";
-		private static const MODE_AV:String = "av";
-		private static const APP_WIDTH:int = 540;
-		private static const LEFT_WIDTH:int = 280;
-		private static const RIGHT_WIDTH:int = 240;
-		private var debugEnabled:Boolean = true;
 		private var sid:String;
 		private var roomid:int;
 		private var audioOnly:Boolean = false;
@@ -49,6 +42,8 @@
 		private var echoPath:int = 256;
 		private var echoSuppression:Boolean = true;
 		private var microphoneRateBest:int = 22;//5, 8, 11, 22, and 44
+		private var selectedMic:int = -1;
+		private var selectedCam:int = -1;
 		private var video:OmVideo;
 		private var recName:String;
 		private var codec:String = OmVideo.CODEC_H264;
@@ -58,42 +53,9 @@
 		private var app:String;
 		[Bindable]
 		private var interview:Boolean = false;
-		[Bindable]
-		private var debugStr:String = "";
-
-		private function setDimensions(width:int, height:int):void {
-			mainSetupGroup.width = width;
-			//mainSetupGroup.height = height;
-		}
-
-		public function debug(str:String):void {
-			if (debugEnabled) {
-				debugStr += str + "\n";
-				trace(str + "\n");
-			}
-		}
-
-		private function store():void {
-			var t:SharedObject = SharedObject.getLocal('userdata');
-			var g:Object = t.data ? t.data : new Object();
-			g["cam"] = cams.selectedItem.data;
-			g["mic"] = mics.selectedItem.data;
-			g["avstored"] = modes.selectedItem.data;
-			g["savecamdata"] = remember.selected;
-			g["width"] = ress.selectedItem.width;
-			g["height"] = ress.selectedItem.height;
-			t.flush();
-		}
-
-		private static function getStoredProp(prop:String):String {
-			//Initialize and get eventually stored property
-			var t:SharedObject = SharedObject.getLocal('userdata');
-			var g:Object = t.data;
-			return g != null ? "" + g[prop] : null;
-		}
 
 		private function init():void {
-			debug("init()");
+			trace("init()");
 			var tla:Object = FlexGlobals.topLevelApplication;
 			sid = tla.parameters['sid'];
 			roomid = tla.parameters['roomid'];
@@ -112,40 +74,8 @@
 			app = tla.parameters['app'];
 		}
 
-		private function selectListItem(combo:ComboBox, selected:int):void {
-			combo.callLater(function ():void {
-				if (combo.dataProvider && combo.dataProvider.length > 0) {
-					combo.selectedItem = combo.dataProvider.getItemAt(selected < combo.dataProvider.length ? selected : 0);
-				}
-			});
-		}
-
-		private function getItemIdx(combo:ComboBox, data:String):int {
-			var idx:int = 0;
-			for (var i:int = 0; i < combo.dataProvider.length; ++i) {
-				if (combo.dataProvider[i].data == data) {
-					idx = i;
-					break;
-				}
-			}
-			return idx;
-		}
-
-		private function fillDeviceList(list:Array, combo:ComboBox, prop:String):int {
-			//Initialize and get eventually stored property
-			var dev:int = parseInt(getStoredProp(prop));
-
-			var items:ArrayCollection = new ArrayCollection();
-			//Get all available devices
-			var foundStoredDev:int = -1;
-			for (var i:int = 0; i < list.length; ++i) {
-				items.addItem({label: list[i], data: i});
-				if (i == dev) {
-					foundStoredDev = i;
-				}
-			}
-			combo.dataProvider = items;
-			return foundStoredDev;
+		private function debug(str:String):void {
+			ExternalInterface.call("console.log", str);
 		}
 
 		private function camAvail():Boolean {
@@ -158,101 +88,41 @@
 
 		private function appInit():void {
 			video = new OmVideo(videoDisplay, codec, protocol + "://" + host + ":" + port + "/" + app);
-			var modItems:ArrayCollection = new ArrayCollection();
-			if (camAvail() && micAvail()) {
-				modItems.addItem({label: getLabel(448), data: MODE_AV});
-			}
-			if (camAvail()) {
-				var cameras:Array = Camera.names;
-				var foundedCam:int = fillDeviceList(cameras, cams, "cam");
-				selectListItem(cams, foundedCam);
-				modItems.addItem({label: getLabel(450), data: MODE_V});
-			}
-			if (micAvail()) {
-				var micros:Array = Microphone.names;
-				var foundedMic:int = fillDeviceList(micros, mics, "mic");
-				selectListItem(mics, foundedMic);
-				modItems.addItem({label: getLabel(449), data: MODE_A});
-			}
-			modItems.addItem({label: getLabel(451), data: MODE_N});
-			modes.dataProvider = modItems;
-
-			var avIdx:int = getItemIdx(modes, getStoredProp("avstored"));
-			debug("selected avIdx::" + avIdx);
-			selectListItem(modes, avIdx);
 
 			var tla:Object = FlexGlobals.topLevelApplication;
-			var resolutions:Array = JSON.parse(tla.parameters['resolutions']) as Array;
-			var resItems:ArrayCollection = new ArrayCollection();
-			var idx:int = 0;
-			var storedWidth:int = parseInt(getStoredProp("width"));
-			var storedHeight:int = parseInt(getStoredProp("height"));
-			for (var i:int = 0; i < resolutions.length; ++i) {
-				var r:Object = resolutions[i];
-				resItems.addItem({label: r.width + 'x' + r.height + ' [' + r.label + ']', width: r.width, height: r.height});
-				if (!isNaN(storedWidth) && storedWidth > 0 && !isNaN(storedHeight) && storedHeight > 0) {
-					if (r.width == storedWidth && r.height == storedHeight) {
-						idx = i;
-					}
-				} else if (r.default) {
-					idx = i;
-				}
-			}
-			ress.dataProvider = resItems;
-			selectListItem(ress, idx);
-			var resI:Object = ress.dataProvider.getItemAt(idx > -1 ? idx : 0);
-			setResolution(resI.width, resI.height, false);
-			setMode(modes.dataProvider.getItemAt(avIdx < modes.dataProvider.length ? avIdx : 0).data);
-
-			remember.selected = true == getStoredProp("savecamdata");
-		}
-
-		public function getLabel(id:int):String {
-			return labels.hasOwnProperty("" + id) ? labels[id] : (debugEnabled ? "[Missing " + id + "]" : "");
-		}
-
-		private function setMode(mode:String):void {
-			var camVisible:Boolean = true;
-			var micVisible:Boolean = true;
-			var textVisible:Boolean = false;
-			switch (mode) {
-				case MODE_AV:
-					break;
-				case MODE_A:
-					camVisible = false;
-					break;
-				case MODE_V:
-					micVisible = false;
-					break;
-				case MODE_N:
-					camVisible = false;
-					micVisible = false;
-					textVisible = true;
-					break;
-				default:
-					debug("no valid device Setup chosen");
-					break;
-			}
-			camGroup.visible = camVisible;
-			micGroup.visible = micVisible;
-			noAv.visible = textVisible;
-			startTest.visible = !textVisible;
-			videoGroup.visible = !textVisible;
-			videoScroller.visible = camVisible;
-			playGroup.visible = !textVisible;
-			resGroup.visible = interview ? false : camVisible;
-			attachCamera();
-		}
-
-		private function modeChanged(e:Event):void {
-			setMode(e.target.selectedItem.data);
+			ExternalInterface.addCallback("getDevices", function ():Object {
+				return {
+					cams: Camera.names
+					, mics: Microphone.names
+				};
+			});
+			ExternalInterface.addCallback("camChanged", function (val:int):void {
+				selectedCam = val;
+				camChanged(null);
+			});
+			ExternalInterface.addCallback("micChanged", function (val:int):void {
+				selectedMic = val;
+				camChanged(null);
+			});
+			ExternalInterface.addCallback("resChanged", function (width:int, height:int):void {
+				setResolution(width, height, true);
+			});
+			ExternalInterface.addCallback("close", function ():void {
+				video.reset();
+			});
+			ExternalInterface.addCallback("init", function (camIdx:int, micIdx:int, width:int, height:int):void {
+				selectedCam = camIdx;
+				selectedMic = micIdx;
+				setResolution(width, height, true);
+			});
+			ExternalInterface.call("VideoSettings.initSwf");
 		}
 
 		private function getMic():Microphone {
 			debug("Entering getMic ...");
 			var _micro:Microphone = null;
-			if (micGroup.visible) {
-				_micro = echoPath == 0 ? Microphone.getMicrophone(mics.selectedItem.data) : Microphone.getEnhancedMicrophone(mics.selectedItem.data);
+			if (selectedMic > -1) {
+				_micro = echoPath == 0 ? Microphone.getMicrophone(selectedMic) : Microphone.getEnhancedMicrophone(selectedMic);
 
 				if (_micro != null && echoPath == 256) {
 					var options:MicrophoneEnhancedOptions = new MicrophoneEnhancedOptions();
@@ -275,31 +145,31 @@
 					debug("canvas.echoSuppression: " + echoSuppression);
 					_micro.setUseEchoSuppression(echoSuppression);
 				}
+				debug("... getMic DONE" + _micro);
 			}
-			debug("... getMic DONE" + _micro);
 			return _micro;
 		}
 
 		private function getCam():Camera {
 			debug("Entering getCam ...");
-			if (!videoScroller.visible) {
-				return null;
-			}
-			var _camera:Camera = Camera.getCamera(cams.selectedItem.data);
-			if (_camera != null && !_camera.muted) {
-				//FIXME need to be unified
-				if (interview) {
-					//we need a fixed frame rate for the videos to merge them later on
-					_camera.setMode(video.width, video.height, 24);
-					debug("IS INTERVIEW ");
-					_camera.setQuality(0, 98);
-				} else {
-					_camera.setMode(video.width, video.height, FPS);
-					debug("IS NO INTERVIEW ");
-					_camera.setQuality(bandwidth, quality);
+			var _camera:Camera = null;
+			if (selectedCam > -1) {
+				_camera = Camera.getCamera("" + selectedCam);
+				if (_camera != null && !_camera.muted) {
+					//FIXME need to be unified
+					if (interview) {
+						//we need a fixed frame rate for the videos to merge them later on
+						_camera.setMode(video.width, video.height, 24);
+						debug("IS INTERVIEW ");
+						_camera.setQuality(0, 98);
+					} else {
+						_camera.setMode(video.width, video.height, FPS);
+						debug("IS NO INTERVIEW ");
+						_camera.setQuality(bandwidth, quality);
+					}
 				}
+				debug("... getCam DONE " + _camera);
 			}
-			debug("... getCam DONE " + _camera);
 			return _camera;
 		}
 
@@ -307,7 +177,7 @@
 			if (!camAvail()) {
 				return;
 			}
-			debug("Camera selected:: " + cams.selectedItem.data);
+			debug("Camera selected:: " + selectedCam);
 			var cam:Camera = getCam();
 			debug("Camera selected:: " + cam);
 			if (cam != null) {
@@ -316,11 +186,14 @@
 					video.attachCamera(cam);
 					cam.addEventListener(StatusEvent.STATUS, function (event:StatusEvent):void {
 						debug("cameraStatusHandler! " + event);
-						cam.removeEventListener(StatusEvent.STATUS, arguments.callee);
-						if (cam.muted) {
-							debug("Unable to connect to active camera.");
-						} else {
-							_attachCamera(cam);
+						//cam.removeEventListener(StatusEvent.STATUS, arguments.callee);
+						switch (event.code) {
+							case 'Camera.Muted':
+								debug("Unable to connect to active camera.");
+								break;
+							case 'Camera.Unmuted':
+								_attachCamera(getCam());
+								break;
 						}
 					});
 				} else {
@@ -345,7 +218,7 @@
 						});
 					}
 				}
- 			}
+			}
 		}
 
 		private function _attachCamera(cam:Camera):void {
@@ -368,141 +241,57 @@
 				debug("onselect WxH :: " + width + "x" + height);
 
 				video.resize(width, height);
-				videoScroller.width = Math.min(width, RIGHT_WIDTH);
-				videoScroller.height = Math.min(height, 200);
-				var newWidth:int = Math.max(APP_WIDTH, APP_WIDTH + videoScroller.width - RIGHT_WIDTH);
-				var newHeight:int = Math.max(500, 500 + videoScroller.height - 180);
 
-				var yPos:int = (startTest as DisplayObject).localToGlobal(new Point()).y;
-				debug("GLOBAL Y:: " + yPos);
-				playGroup.y = Math.max(yPos, videoScroller.height);
-				setDimensions(newWidth, newHeight);
 				if (attach) {
 					attachCamera();
 				}
 			}
 		}
 
-		private function resChanged(e:Event):void {
-			setResolution(e.target.selectedItem.width, e.target.selectedItem.height, true);
-		}
-
 		private function camChanged(e:Event):void {
 			attachCamera();
 		}
 
-		private function startConf(e:Event):void {
-			store();
-		}
-
 		private function playTestRecording():void {
 			video.play(recName);
 		}
 
 		private function startTestRecording():void {
-			if (!noAv.visible) {
-				startTest.enabled = false;
-				play.enabled = false;
-				var counter:int = 5;
-				timerText.visible = true;
-				timerText.text = "5 sec";
-				var recTimer:Timer = new Timer(1000, counter);
-				var t:Date = new Date();
-				recName = "TEST_SETUP_" + t.getTime();
-				var mic:Microphone = getMic();
-				video.record(recName, getCam(), mic, function ():void {
-					mic.addEventListener(ActivityEvent.ACTIVITY, micActivityHandler);
-					//mic.onA
-					var micTimer:Timer = new Timer(100, 0);
-					micTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
-						fill.width =  mic.activityLevel * RIGHT_WIDTH / 100;
-						trace("activity: " + mic.activityLevel);
-					});
-					recTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
-						timerText.text = --counter + " sec";
-						if (counter == 0) {
-							timerText.visible = false;
-							startTest.enabled = true;
-							play.enabled = true;
-							playTestRecording();
-							micTimer.stop();
-							mic.removeEventListener(ActivityEvent.ACTIVITY, micActivityHandler);
-						}
-					});
-					recTimer.start();
-					micTimer.start();
+			var counter:int = 5;
+			timerText.visible = true;
+			timerText.text = "5 sec";
+			var recTimer:Timer = new Timer(1000, counter);
+			var t:Date = new Date();
+			recName = "TEST_SETUP_" + t.getTime();
+			var mic:Microphone = getMic();
+			video.record(recName, getCam(), mic, function ():void {
+				mic.addEventListener(ActivityEvent.ACTIVITY, micActivityHandler);
+				//mic.onA
+				var micTimer:Timer = new Timer(100, 0);
+				micTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
+					//FIXME TODO fill.width = mic.activityLevel * RIGHT_WIDTH / 100;
+					debug("activity: " + mic.activityLevel);
 				});
-			}
+				recTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
+					timerText.text = --counter + " sec";
+					if (counter == 0) {
+						timerText.visible = false;
+						playTestRecording();
+						micTimer.stop();
+						mic.removeEventListener(ActivityEvent.ACTIVITY, micActivityHandler);
+					}
+				});
+				recTimer.start();
+				micTimer.start();
+			});
 		}
 
-		function micActivityHandler(event:ActivityEvent):void{
+		private function micActivityHandler(event:ActivityEvent):void {
 			//Do nothing, it just need to be there.
 		}
-	]]>
-	</fx:Script>
+	]]></fx:Script>
 
-	<s:Group id="mainSetupGroup" width="{APP_WIDTH}">
-		<s:layout>
-			<s:VerticalLayout paddingLeft="5" paddingRight="5"/>
-		</s:layout>
-		<mx:Text width="100%" fontWeight="bold" text="{getLabel(758)}"/>
-		<s:HGroup>
-			<s:VGroup width="{LEFT_WIDTH}">
-				<mx:Text text="{getLabel(447)}"/>
-				<mx:ComboBox id="modes" width="{LEFT_WIDTH}" change="modeChanged(event)"/>
-				<s:VGroup id="av">
-					<s:VGroup id="camGroup">
-						<mx:Text text="{getLabel(52)}"/>
-						<mx:ComboBox id="cams" width="{LEFT_WIDTH}" change="camChanged(event)"/>
-					</s:VGroup>
-					<s:VGroup id="micGroup">
-						<mx:Text text="{getLabel(53)}"/>
-						<mx:ComboBox id="mics" width="{LEFT_WIDTH}"/>
-					</s:VGroup>
-					<s:VGroup id="resGroup">
-						<s:Group><mx:Text text="{getLabel(1429)}"/><mx:Image x="260" source="../images/error.png" toolTip="{getLabel(1430)}"/></s:Group>
-						<mx:ComboBox id="ress" width="{LEFT_WIDTH}" change="resChanged(event)"/>
-					</s:VGroup>
-					<s:Group width="100%">
-						<s:layout><s:HorizontalLayout horizontalAlign="right"/></s:layout>
-						<s:Button id="startTest" label="{getLabel(775)}" click="startTestRecording()"/><!--FIXME should be disabled until stream is attached-->
-					</s:Group>
-				</s:VGroup>
-				<mx:Text text="{getLabel(452)}" id="noAv" visible="false"/>
-			</s:VGroup>
-			<s:Group id="videoGroup">
-				<s:Scroller id="videoScroller">
-					<s:Group id="videoScrollGroup">
-						<mx:UIComponent id="videoDisplay" width="0" height="0" />
-					</s:Group>
-				</s:Scroller>
-				<s:Label id="timerText" height="20" width="45" x="{videoGroup.width - 60}" y="5" paddingLeft="5" paddingTop="5"
-						visible="false" backgroundColor="0xf5f5f5" fontWeight="bold"><s:text></s:text></s:Label>
-				<s:VGroup id="playGroup">
-					<s:Group>
-						<s:Graphic x="0" z="1">
-							<s:Rect width="{RIGHT_WIDTH}" height="20">
-								<s:fill><s:SolidColor color="white"/></s:fill>
-								<s:stroke><s:SolidColorStroke color="black" weight="2"/></s:stroke>
-							</s:Rect>
-						</s:Graphic>
-						<mx:Image id="fill" source="../images/level_meter.png" x="2" y="1" z="3" width="0"/>
-						<mx:Text text="{getLabel(767)}" x="0" z="5"/>
-					</s:Group>
-					<s:Group width="100%">
-						<s:layout><s:HorizontalLayout horizontalAlign="right"/></s:layout>
-						<s:Button id="play" label="{getLabel(764)}" enabled="false" click="playTestRecording()"/>
-					</s:Group>
-				</s:VGroup>
-			</s:Group>
-		</s:HGroup>
-		<s:HGroup><mx:Image source="../images/info.png"/><mx:Text text="{getLabel(765)}" width="{APP_WIDTH - 70}"/></s:HGroup>
-		<s:Group width="100%">
-			<s:layout><s:HorizontalLayout horizontalAlign="right"/></s:layout>
-			<s:Button id="cancel" label="{getLabel(918)}"/>
-			<s:Button id="start" label="{getLabel(interview ? 54 : 761)}" click="startConf(event)"/>
-		</s:Group>
-		<s:CheckBox id="remember" label="{getLabel(762)}" />
-	</s:Group>
-	<s:TextArea id="traceArea" y="460" width="400" height="400" text="{debugStr}"/>
+	<mx:UIComponent id="videoDisplay" width="0" height="0" />
+	<s:Label id="timerText" height="20" width="45" x="20" y="5" paddingLeft="5" paddingTop="5"
+			 visible="false" backgroundColor="0xf5f5f5" fontWeight="bold"><s:text></s:text></s:Label>
 </s:Application>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5d85a641/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index a40e518..a479791 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -76,6 +76,7 @@ import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.protocol.http.ClientProperties;
 import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
@@ -121,7 +122,8 @@ public class RoomPanel extends BasePanel {
 				URL url = new URL(WebSession.get().getExtendedProperties().getCodebase());
 				String path = url.getPath();
 				path = path.substring(1, path.indexOf('/', 2) + 1);
-				target.appendJavaScript(String.format("initVideo(%s);", new JSONObject()
+				ClientProperties cp = WebSession.get().getClientInfo().getProperties();
+				target.appendJavaScript(String.format("VideoSettings.init(%s);", new JSONObject()
 						.put("uid", getClient().getUid())
 						.put("audioOnly", r.isAudioOnly())
 						.put("SID", WebSession.getSid())
@@ -130,8 +132,7 @@ public class RoomPanel extends BasePanel {
 						.put("host", url.getHost())
 						//.put("port", cfgDao.getConfValue(CONFIG_FLASH_PORT, String.class, ""))
 						.put("app", path + r.getId())
-						.put("labels", SwfPanel.getStringLabels("448", "449", "450", "451", "758", "447", "52", "53"
-								, "1429", "1430", "775", "452", "767", "764", "765", "918", "54", "761", "762"))
+						.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct")
 						.toString()
 						));
 			} catch (NullPointerException|MalformedURLException e) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5d85a641/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index 1fb06cc..c9109a2 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -16,45 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-function initVideo(_options) {
-	return; //commented until video is implemented
-	var options = $.extend({bgcolor: "#ffffff"
-		, resolutions: JSON.stringify([{label: "4:3 (~6 KByte/sec)", width: 40, height: 30}
-			, {label: "4:3 (~12 KByte/sec)", width: 80, height: 60}
-			, {label: "4:3 (~20 KByte/sec)", width: 120, height: 90, "default": true}
-			, {label: "QQVGA 4:3 (~36 KByte/sec)", width: 160, height: 120}
-			, {label: "4:3 (~40 KByte/sec)", width: 240, height: 180}
-			, {label: "HVGA 4:3 (~56 KByte/sec)", width: 320, height: 240}
-			, {label: "4:3  (~60 KByte/sec)", width: 480, height: 360}
-			, {label: "4:3 (~68 KByte/sec)", width: 640, height: 480}
-			, {label: "XGA 4:3", width: 1024, height: 768}
-			, {label: "16:9", width: 256, height: 150}
-			, {label: "WQVGA 9:5", width: 432, height: 240}
-			, {label: "pseudo 16:9", width: 480, height: 234}
-			, {label: "16:9", width: 512, height: 300}
-			, {label: "nHD 16:9", width: 640, height: 360}
-			, {label: "16:9", width: 1024, height: 600}])
-		}, _options);
+function initVideo(el, id, options) {
 	var type = 'application/x-shockwave-flash';
 	var src = 'public/main.swf?cache' + new Date().getTime();
-	var r = $('<div class="room video">').attr("id", "video" + options.uid);
-	var o = $('<object>').attr('type', type).attr('data', src).attr('width', 640).attr('height', 480);
+	var o = $('<object>').attr('id', id).attr('type', type).attr('data', src).attr('width', options.width).attr('height', options.height);
 	o.append($('<param>').attr('name', 'quality').attr('value', 'best'))
-		.append($('<param>').attr('name', 'wmode').attr('value', 'transparent'))
+		.append($('<param>').attr('name', 'wmode').attr('value', options.wmode))
 		.append($('<param>').attr('name', 'allowscriptaccess').attr('value', 'sameDomain'))
 		.append($('<param>').attr('name', 'allowfullscreen').attr('value', 'false'))
 		.append($('<param>').attr('name', 'flashvars').attr('value', $.param(options)));
-	$('#roomMenu').parent().append(r.append(o));
-	/*
-			.attr('wmode', 'window').attr('allowfullscreen', true)
-			.attr('width', options.width).attr('height', options.height)
-			.attr('id', 'lzapp').attr('name', 'lzapp')
-			.attr('flashvars', escape($.param(options)))
-			.attr('swliveconnect', true).attr('align', 'middle')
-			.attr('allowscriptaccess', 'sameDomain').attr('type', 'application/x-shockwave-flash')
-			.attr('pluginspage', 'http://www.macromedia.com/go/getflashplayer')
-	*/
-	r.dialog({dialogClass: "video"});
+	el.append(o);
+	return o;
 }
 
 function setRoomSizes() {
@@ -105,7 +77,6 @@ function roomLoad() {
 			setRoomSizes();
 		}
 	});
-	VideoSettings.init();
 	Wicket.Event.subscribe("/websocket/closed", roomClosed);
 }
 function roomUnload() {
@@ -122,10 +93,25 @@ function startPrivateChat(el) {
 	$('#chatMessage .wysiwyg-editor').click();
 }
 var VideoSettings = (function() {
-	var self = {}, vs, lm;
-	function _init() {
+	var self = {}, vs, lm, swf, s, cam, mic, res, inited = false;
+	function _load() {
+		s = {};
+		try {
+			s = JSON.parse(localStorage.getItem('openmeetings')) || s;
+		} catch (e) {}
+		if (!s.video) {
+			s.video = {};
+		}
+	}
+	function _save() {
+		localStorage.setItem('openmeetings', JSON.stringify(s));
+	}
+	function _init(options) {
 		vs = $('#video-settings');
 		lm = vs.find('.level-meter');
+		cam = vs.find('select.cam');
+		mic = vs.find('select.mic');
+		res = vs.find('select.cam-resolution');
 		vs.dialog({
 			classes: {
 				'ui-dialog': 'ui-corner-all video'
@@ -139,6 +125,7 @@ var VideoSettings = (function() {
 						primary: "ui-icon-disk"
 					}
 					, click: function() {
+						_save();
 						vs.dialog("close");
 					}
 				}
@@ -151,7 +138,60 @@ var VideoSettings = (function() {
 			]
 		});
 		lm.progressbar({ value: 0 });
+		options.width = 300;
+		options.height = 200;
+		swf = initVideo(vs.find('.vid-block .video-conainer'), 'video-settings-swf', options)[0];
+		vs.find('input, button').prop('disabled', true);
 		vs.find('button').button();
+		_load();
+	}
+	function _readValues() {
+		s.video.cam = cam.val();
+		s.video.mic = mic.val();
+		var o = res.find('option:selected').data();
+		s.video.width = o.width;
+		s.video.height = o.height;
+		$(swf).attr('width', Math.max(300, s.video.width)).attr('height', Math.max(200, s.video.height));
+	}
+	function _initSwf() {
+		if (!inited) {
+			var obj = swf.getDevices();
+			for (var i = 0; i < obj.cams.length; ++i) {
+				var o = $('<option></option>').attr('value', i).text(obj.cams[i]);
+				if (i == s.video.cam) {
+					o.prop('selected', true);
+				}
+				cam.append(o);
+			}
+			cam.prop('disabled', false).change(function() {
+				_readValues();
+				swf.camChanged(s.video.cam);
+			});
+			for (var i = 0; i < obj.mics.length; ++i) {
+				var o = $('<option></option>').attr('value', i).text(obj.mics[i]);
+				if (i == s.video.mic) {
+					o.prop('selected', true);
+				}
+				mic.append(o);
+			}
+			mic.prop('disabled', false).change(function() {
+				_readValues();
+				swf.micChanged(s.video.mic);
+			});
+			res.change(function() {
+				_readValues();
+				swf.resChanged(s.video.width, s.video.height);
+			});
+			res.find('option').each(function(idx) {
+				var o = $(this).data();
+				if (o.width == s.video.width && o.height == s.video.height) {
+					$(this).prop('selected', true);
+					return false;
+				}
+			});
+		}
+		_readValues();
+		swf.init(s.video.cam, s.video.mic, s.video.width, s.video.height);
 	}
 	function _open(interview) {
 		var rr = vs.find('.cam-resolution').parent('.sett-row');
@@ -164,6 +204,7 @@ var VideoSettings = (function() {
 	}
 	return {
 		init: _init
+		, initSwf: _initSwf
 		, open: _open
 		, close: function() { vs.dialog('close'); }
 	};

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5d85a641/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
index 9e5b7ac..56a41c1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
@@ -87,16 +87,15 @@
 						</select>
 					</div>
 				</div>
-				<div class="sett-row">
-					<div class="align-right"><button><wicket:message key="775"/></button></div>
+				<div class="sett-row right">
+					<div><button><wicket:message key="775"/></button></div>
 				</div>
 			</div>
 			<div class="vid-block">
-				<div>
-				</div>
+				<div class="video-conainer"></div>
 				<div class="level-meter"></div>
-				<div class="sett-row">
-					<div class="align-right"><button><wicket:message key="764"/></button></div>
+				<div class="sett-row right">
+					<div><button><wicket:message key="764"/></button></div>
 				</div>
 			</div>
 		</div>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5d85a641/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index 18f6f4c..36fab21 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -390,6 +390,13 @@
 .ui-dialog.video .sett-row {
 	padding-top: 10px;
 }
+.ui-dialog.video .sett-row.right {
+	text-align: right;
+}
+.ui-dialog.video .vid-block .video-conainer {
+	overflow: auto;
+	max-height: 300px;
+}
 .ui-dialog.video .sett-row select, .ui-dialog.video .level-meter {
 	width: 250px;
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5d85a641/openmeetings-web/src/main/webapp/js/openmeetings_functions.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/js/openmeetings_functions.js b/openmeetings-web/src/main/webapp/js/openmeetings_functions.js
deleted file mode 100644
index 53c3d3a..0000000
--- a/openmeetings-web/src/main/webapp/js/openmeetings_functions.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-  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.
-  
-*/
-/*
- * Functions to be included in the HTML wrapper,
- * see the templates dir (*.vm) for the include statements
- *  
- */ 
-
-function getBrowserInfo() {
-	//alert(navigator.userAgent);
-	document.getElementById("lzapp").getBrowserInfoCallback(navigator.userAgent);
-}
-
-function getBrowserLang() {
-	//alert(navigator.userAgent);
-	document.getElementById("lzapp").getBrowserLangCallback(navigator.language);
-}
-
-function redirectToUrl(url) {
-	//alert(navigator.userAgent);
-	window.location = url;
-	
-	document.getElementById("lzapp").redirectToUrlCallback("ok");
-}
-
-function loadingComplete() {
-	document.getElementById("swfloading").style.display = 'none';
-	var lzApp = document.getElementById("lzappContainer");
-	lzApp.style.width = '100%';
-	lzApp.style.height = '100%';
-}
-
-function getTimeZoneOffsetMinutes() {
-	var rightNow = new Date(), std_time_offset = -rightNow.getTimezoneOffset();
-	for (var i = 0; i < 12; ++i) {
-		var d = new Date(rightNow.getFullYear(), i, 1, 0, 0, 0, 0), offset = -d.getTimezoneOffset();
-		if (offset < std_time_offset) {
-			std_time_offset = offset;
-			break;
-		}
-	}
-	return std_time_offset;
-}
-
-function getTimeZoneOffset() {
-	document.getElementById("lzapp").getTimeZoneOffsetCallback(getTimeZoneOffsetMinutes()/60);
-}


[37/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1631] polls seems to be fixed

Posted by so...@apache.org.
[OPENMEETINGS-1631] polls seems to be fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/ccca6bdb
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/ccca6bdb
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/ccca6bdb

Branch: refs/heads/master
Commit: ccca6bdb3dbf812f6bd23a2ea764e05073a78ebb
Parents: ac232ec
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 19 03:29:00 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 19 03:29:00 2017 +0000

----------------------------------------------------------------------
 .../org/apache/openmeetings/web/room/menu/RoomMenuPanel.java | 2 ++
 .../apache/openmeetings/web/room/poll/PollResultsDialog.java | 8 ++------
 .../org/apache/openmeetings/web/room/poll/VoteDialog.java    | 3 +++
 3 files changed, 7 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ccca6bdb/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
index 86fa8f0..37d7115 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
@@ -325,6 +325,8 @@ public class RoomMenuPanel extends Panel {
 		RoomPoll rp = getBean(PollDao.class).getByRoom(room.getRoom().getId());
 		if (rp != null) {
 			vote.updateModel(handler, rp);
+		} else {
+			vote.close(handler, null);
 		}
 		if (createdBy != null && !getUserId().equals(createdBy)) {
 			vote.open(handler);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ccca6bdb/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/PollResultsDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/PollResultsDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/PollResultsDialog.java
index 866b6b6..3f3b210 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/PollResultsDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/PollResultsDialog.java
@@ -101,8 +101,8 @@ public class PollResultsDialog extends AbstractDialog<RoomPoll> {
 
 					RoomPoll p = getBean(PollDao.class).get(id);
 					selForm.select.setModelObject(p);
-					dispForm.updateModel(p, false, handler);
-					//TODO result dialogs of other users should also be updated
+					dispForm.updateModel(p, true, handler);
+					sendRoom(new RoomMessage(roomId, getUserId(), RoomMessage.Type.pollUpdated));
 				}
 			}
 		});
@@ -278,10 +278,6 @@ public class PollResultsDialog extends AbstractDialog<RoomPoll> {
 		ChartConfiguration<Long> cfg = barChart.getChartConfiguration();
 		cfg.setLegend(null).setHighlighter(h);
 		cfg.axesInstance().setXaxis(null);
-		/*
-		 * cfg.axesInstance().xAxisInstance().setRenderer(JqPlotResources.
-		 * AxisTickRenderer);
-		 */
 		cfg.axesInstance().yAxisInstance().setTicks(ticks).setRenderer(JqPlotResources.CategoryAxisRenderer);
 		return barChart;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ccca6bdb/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/VoteDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/VoteDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/VoteDialog.java
index 4b7ad40..f3d350e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/VoteDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/VoteDialog.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.web.room.poll;
 
+import static org.apache.openmeetings.core.util.WebSocketHelper.sendRoom;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 
@@ -30,6 +31,7 @@ import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.RoomPoll;
 import org.apache.openmeetings.db.entity.room.RoomPollAnswer;
 import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
@@ -121,6 +123,7 @@ public class VoteDialog extends AbstractFormDialog<RoomPollAnswer> {
 		a.setVoteDate(new Date());
 		a.getRoomPoll().getAnswers().add(a);
 		getBean(PollDao.class).update(a.getRoomPoll());
+		sendRoom(new RoomMessage(a.getRoomPoll().getRoom().getId(), getUserId(), RoomMessage.Type.pollUpdated));
 	}
 
 	@Override


[05/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1620] unenrool seems to be fixed

Posted by so...@apache.org.
[OPENMEETINGS-1620] unenrool seems to be fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/89b00fdc
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/89b00fdc
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/89b00fdc

Branch: refs/heads/master
Commit: 89b00fdc38dbd058a0690c1b80243a894d25b93b
Parents: 6b542f3
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 2 03:39:12 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 2 03:39:12 2017 +0000

----------------------------------------------------------------------
 .../src/main/java/org/apache/openmeetings/web/room/RoomPanel.java | 2 ++
 .../java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/89b00fdc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index ac3b3e4..a40e518 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -20,6 +20,7 @@ package org.apache.openmeetings.web.room;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.addUserToRoom;
+import static org.apache.openmeetings.web.app.Application.exitRoom;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getOnlineClient;
 import static org.apache.openmeetings.web.app.Application.getRoomClients;
@@ -434,6 +435,7 @@ public class RoomPanel extends BasePanel {
 								handler.add(room.setVisible(false));
 								getMainPanel().getChat().toggle(handler, false);
 								clientKicked.open(handler);
+								exitRoom(getClient());
 							}
 						}
 						break;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/89b00fdc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
index 74040e3..86fa8f0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
@@ -20,6 +20,7 @@ package org.apache.openmeetings.web.room.menu;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPLICATION_BASE_URL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_REDIRECT_URL_FOR_EXTERNAL_KEY;
+import static org.apache.openmeetings.web.app.Application.exitRoom;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.util.GroupLogoResourceReference.getUrl;
@@ -336,7 +337,7 @@ public class RoomMenuPanel extends Panel {
 
 	public void exit(IPartialPageRequestHandler handler) {
 		if (WebSession.getRights().contains(User.Right.Dashboard)) {
-			Application.exitRoom(room.getClient());
+			exitRoom(room.getClient());
 			room.getMainPanel().updateContents(ROOMS_PUBLIC, handler);
 		} else {
 			String url = getBean(ConfigurationDao.class).getConfValue(CONFIG_REDIRECT_URL_FOR_EXTERNAL_KEY, String.class, "");


[08/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1610] time picker should be fixed

Posted by so...@apache.org.
[OPENMEETINGS-1610] time picker should be fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/d006c543
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/d006c543
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/d006c543

Branch: refs/heads/master
Commit: d006c543215cb72a1a131f9ffd8a075319d63b8b
Parents: 4e751ae
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 2 14:31:10 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 2 14:31:10 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/web/common/OmDateTimePicker.java     | 14 +++++++++-----
 .../web/user/calendar/AppointmentDialog.java          |  8 +++++++-
 2 files changed, 16 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/d006c543/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmDateTimePicker.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmDateTimePicker.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmDateTimePicker.java
index 1ea0411..6e7cf9e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmDateTimePicker.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmDateTimePicker.java
@@ -28,7 +28,6 @@ import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.model.IModel;
 
 import com.googlecode.wicket.jquery.core.Options;
-import com.googlecode.wicket.kendo.ui.KendoCultureHeaderItem;
 import com.googlecode.wicket.kendo.ui.form.datetime.local.DatePicker;
 import com.googlecode.wicket.kendo.ui.form.datetime.local.DateTimePicker;
 import com.googlecode.wicket.kendo.ui.form.datetime.local.TimePicker;
@@ -37,22 +36,27 @@ public class OmDateTimePicker extends DateTimePicker {
 	private static final long serialVersionUID = 1L;
 
 	public OmDateTimePicker(String id, IModel<LocalDateTime> model) {
-		super(id, model);
+		super(id, model, WebSession.get().getLocale());
 	}
 
 	@Override
 	protected DatePicker newDatePicker(String id, IModel<LocalDate> model, Locale locale, String datePattern, Options options) {
-		return new DatePicker(id, model, WebSession.get().getLocale());
+		DatePicker dp = super.newDatePicker(id, model, locale, datePattern, options);
+		dp.setLabel(getLabel());
+		return dp;
 	}
 
 	@Override
 	protected TimePicker newTimePicker(String id, IModel<LocalTime> model, Locale locale, String timePattern, Options options) {
-		return new TimePicker(id, model, WebSession.get().getLocale());
+		TimePicker tp = super.newTimePicker(id, model, locale, timePattern, options);
+		tp.setLabel(getLabel());
+		return tp;
 	}
 
 	@Override
 	public void renderHead(IHeaderResponse response) {
 		super.renderHead(response);
-		response.render(KendoCultureHeaderItem.of(WebSession.get().getLocale()));
+		//FIXME TODO this is remain here until localized AM/PM will be correctly handled
+		//response.render(KendoCultureHeaderItem.of(WebSession.get().getLocale()));
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/d006c543/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
index 976a206..bb7e55a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
@@ -375,7 +375,6 @@ public class AppointmentDialog extends AbstractFormDialog<Appointment> {
 			add(feedback.setOutputMarkupId(true));
 			//General
 			add(new RequiredTextField<String>("title").setLabel(Model.of(Application.getString(572))));
-			add(start.setRequired(true), end.setRequired(true));
 			add(ownerPanel.add(owner));
 			boolean showGroups = AuthLevelUtil.hasAdminLevel(getRights());
 			add(rdi.add(new AjaxFormChoiceComponentUpdatingBehavior() {
@@ -476,6 +475,13 @@ public class AppointmentDialog extends AbstractFormDialog<Appointment> {
 			add(cals.setNullValid(true).setLabel(Model.of("calendar")).setOutputMarkupId(true));
 		}
 
+		@Override
+		protected void onInitialize() {
+			super.onInitialize();
+			add(start.setLabel(Model.of(getString("570"))).setRequired(true)
+					, end.setLabel(Model.of(getString("571"))).setRequired(true));
+		}
+
 		private List<Room> getRoomList() {
 			//FIXME need to be reviewed
 			List<Room> result = new ArrayList<>();


[21/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] settings dialog seems to be implemented

Posted by so...@apache.org.
[OPENMEETINGS-551] settings dialog seems to be implemented


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/8599b3df
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/8599b3df
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/8599b3df

Branch: refs/heads/master
Commit: 8599b3df50907a1e4e505b0ec1541d64bd7ee730
Parents: 5d85a64
Author: Maxim Solodovnik <so...@apache.org>
Authored: Tue Apr 11 15:52:14 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Tue Apr 11 15:52:14 2017 +0000

----------------------------------------------------------------------
 .../remote/red5/ScopeApplicationAdapter.java    |  31 +++-
 openmeetings-flash/src/main/flex/main.mxml      | 152 +++++++++----------
 .../flex/org/apache/openmeetings/OmVideo.as     | 108 +++++++------
 .../installation/ImportInitvalues.java          |   8 +
 .../util/OpenmeetingsVariables.java             |   4 +
 .../web/pages/auth/SignInDialog.html            |   5 +-
 .../web/pages/install/InstallWizardPage.html    |   7 +-
 .../apache/openmeetings/web/room/RoomPanel.java |   5 +-
 .../apache/openmeetings/web/room/SwfPanel.java  |   1 -
 .../org/apache/openmeetings/web/room/room.js    |  54 +++++--
 .../web/room/sidebar/RoomSidebar.html           |   4 +-
 .../web/room/sidebar/icon/SettingsIcon.java     |   3 +-
 12 files changed, 222 insertions(+), 160 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
index 2a13a47..6a44556 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
@@ -19,10 +19,15 @@
 package org.apache.openmeetings.core.remote.red5;
 
 import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE_PROXY;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_VIDEO_CODEC;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
 import java.awt.Point;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
@@ -32,6 +37,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicLong;
@@ -92,6 +98,8 @@ import org.red5.server.api.stream.IBroadcastStream;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import com.github.openjson.JSONObject;
+
 public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter implements IPendingServiceCallback {
 	private static final Logger log = Red5LoggerFactory.getLogger(ScopeApplicationAdapter.class, webAppRootKey);
 	private static final String SECURITY_CODE_PARAM = "securityCode";
@@ -108,7 +116,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	@Autowired
 	private RecordingService recordingService;
 	@Autowired
-	private ConfigurationDao configurationDao;
+	private ConfigurationDao cfgDao;
 	@Autowired
 	private AppointmentDao appointmentDao;
 	@Autowired
@@ -125,6 +133,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	private RecordingDao recordingDao;
 	@Autowired
 	private ServerDao serverDao;
+	private JSONObject flashSettings;
 
 	private static AtomicLong broadCastCounter = new AtomicLong(0);
 
@@ -147,6 +156,18 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			getCryptKey();
 
 			// init your handler here
+			Properties props = new Properties();
+			try (InputStream is = new FileInputStream(new File(new File(OmFileHelper.getRootDir(), "conf"), "red5.properties"))) {
+				props.load(is);
+			}
+			flashSettings = new JSONObject()
+					.put("secure", "yes".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE, String.class, "no")))
+					.put("proxyType", cfgDao.getConfValue(CONFIG_FLASH_SECURE_PROXY, String.class, "none"))
+					.put("rtmpPort", props.getProperty("rtmp.port"))
+					.put("rtmpsPort", props.getProperty("rtmps.port"))
+					.put("videoCodec", cfgDao.getConfValue(CONFIG_FLASH_VIDEO_CODEC, String.class, "h263"))
+					.put("fps", cfgDao.getConfValue(OpenmeetingsVariables.CONFIG_FLASH_VIDEO_FPS, Integer.class, "30"))
+					;
 
 			for (String scopeName : scope.getScopeNames()) {
 				log.debug("scopeName :: " + scopeName);
@@ -1847,11 +1868,11 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	}
 
 	private boolean getWhiteboardDrawStatus() {
-		return configurationDao.getWhiteboardDrawStatus();
+		return cfgDao.getWhiteboardDrawStatus();
 	}
 
 	public String getCryptKey() {
-		return configurationDao.getCryptKey();
+		return cfgDao.getCryptKey();
 	}
 
 	public IScope getRoomScope(String room) {
@@ -1940,4 +1961,8 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 
 		sendMessageToCurrentScope("addNewUser", currentClient, false);
 	}
+
+	public JSONObject getFlashSettings() {
+		return flashSettings;
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-flash/src/main/flex/main.mxml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/main.mxml b/openmeetings-flash/src/main/flex/main.mxml
index ec3792c..1e3867b 100644
--- a/openmeetings-flash/src/main/flex/main.mxml
+++ b/openmeetings-flash/src/main/flex/main.mxml
@@ -21,8 +21,8 @@
 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
 		xmlns:s="library://ns.adobe.com/flex/spark"
 		xmlns:mx="library://ns.adobe.com/flex/mx"
-		width="570" height="900" pageTitle="Openmeetings"
-		preinitialize="init()" fontSize="12" applicationComplete="appInit()">
+		width="570" height="900" pageTitle="Openmeetings" fontSize="12"
+		applicationComplete="appInit(event)" uncaughtError="uncaughtError(event)">
 	<fx:Declarations>
 		<!-- Place non-visual elements (e.g., services, value objects) here -->
 		<mx:TraceTarget/>
@@ -32,10 +32,7 @@
 
 		import org.apache.openmeetings.OmVideo;
 
-		private var sid:String;
-		private var roomid:int;
 		private var audioOnly:Boolean = false;
-		private var labels:Object = new Object();
 		private var FPS:int;
 		private var bandwidth:int = 0;
 		private var quality:int = 100;
@@ -46,36 +43,12 @@
 		private var selectedCam:int = -1;
 		private var video:OmVideo;
 		private var recName:String;
-		private var codec:String = OmVideo.CODEC_H264;
-		private var protocol:String;
-		private var host:String;
-		private var port:String;
-		private var app:String;
+		private var mic:Microphone = null;
 		[Bindable]
 		private var interview:Boolean = false;
 
-		private function init():void {
-			trace("init()");
-			var tla:Object = FlexGlobals.topLevelApplication;
-			sid = tla.parameters['sid'];
-			roomid = tla.parameters['roomid'];
-			audioOnly = 'true' == tla.parameters['audioOnly'];
-			interview = 'true' == tla.parameters['interview'];
-			var _fps:int = parseInt(tla.parameters['fps']);
-			FPS = interview ? 24 : (isNaN(_fps) || _fps < 1 ? 30 : _fps);
-
-			var lbls:Array = JSON.parse(tla.parameters['labels']) as Array;
-			for (var i:int = 0; i < lbls.length; ++i) {
-				labels[lbls[i].id] = lbls[i].value;
-			}
-			protocol = tla.parameters['protocol'];
-			host = tla.parameters['host'];
-			port = tla.parameters['port'];
-			app = tla.parameters['app'];
-		}
-
-		private function debug(str:String):void {
-			ExternalInterface.call("console.log", str);
+		private function debug(...rest):void {
+			ExternalInterface.call("console.log", rest);
 		}
 
 		private function camAvail():Boolean {
@@ -86,10 +59,15 @@
 			return Microphone.names.length > 0;
 		}
 
-		private function appInit():void {
-			video = new OmVideo(videoDisplay, codec, protocol + "://" + host + ":" + port + "/" + app);
-
+		private function appInit(evt:Event):void {
 			var tla:Object = FlexGlobals.topLevelApplication;
+			debug("appInit()", tla.parameters);
+			audioOnly = 'true' == tla.parameters['audioOnly'];
+			interview = 'true' == tla.parameters['interview'];
+			var _fps:int = parseInt(tla.parameters['fps']);
+			FPS = (isNaN(_fps) || _fps < 1 ? 30 : _fps);
+			video = new OmVideo(videoDisplay, tla.parameters);
+
 			ExternalInterface.addCallback("getDevices", function ():Object {
 				return {
 					cams: Camera.names
@@ -115,25 +93,34 @@
 				selectedMic = micIdx;
 				setResolution(width, height, true);
 			});
+			ExternalInterface.addCallback("startRec", function ():void {
+				startTestRecording();
+			});
+			ExternalInterface.addCallback("play", function ():void {
+				playTestRecording();
+			});
 			ExternalInterface.call("VideoSettings.initSwf");
 		}
 
+		private function uncaughtError(e:UncaughtErrorEvent):void {
+			debug("Unexpected ERROR", e);
+		}
+
 		private function getMic():Microphone {
 			debug("Entering getMic ...");
 			var _micro:Microphone = null;
 			if (selectedMic > -1) {
 				_micro = echoPath == 0 ? Microphone.getMicrophone(selectedMic) : Microphone.getEnhancedMicrophone(selectedMic);
 
-				if (_micro != null && echoPath == 256) {
-					var options:MicrophoneEnhancedOptions = new MicrophoneEnhancedOptions();
-					options.mode = MicrophoneEnhancedMode.FULL_DUPLEX;
-					options.echoPath = 256;
-					options.nonLinearProcessing = true;
-					_micro.enhancedOptions = options;
-					debug("echoPath set to 256 " + _micro.enhancedOptions);
-				}
-
 				if (_micro != null) {
+					if (echoPath == 256) {
+						var options:MicrophoneEnhancedOptions = new MicrophoneEnhancedOptions();
+						options.mode = MicrophoneEnhancedMode.FULL_DUPLEX;
+						options.echoPath = echoPath;
+						options.nonLinearProcessing = true;
+						_micro.enhancedOptions = options;
+						debug("echoPath set to " + echoPath + ", " + _micro.enhancedOptions);
+					}
 					_micro.codec = SoundCodec.NELLYMOSER;
 					_micro.framesPerPacket = 1;
 					_micro.setSilenceLevel(0, 2000);
@@ -186,12 +173,13 @@
 					video.attachCamera(cam);
 					cam.addEventListener(StatusEvent.STATUS, function (event:StatusEvent):void {
 						debug("cameraStatusHandler! " + event);
-						//cam.removeEventListener(StatusEvent.STATUS, arguments.callee);
+						cam.removeEventListener(StatusEvent.STATUS, arguments.callee);
 						switch (event.code) {
 							case 'Camera.Muted':
 								debug("Unable to connect to active camera.");
 								break;
 							case 'Camera.Unmuted':
+								ExternalInterface.call("VideoSettings.allowRec", true);
 								_attachCamera(getCam());
 								break;
 						}
@@ -200,20 +188,22 @@
 					_attachCamera(cam);
 				}
 			} else {
-				var mic:Microphone = getMic();
-				if (mic != null) {
-					if (mic.muted) {
+				var _mic:Microphone = getMic();
+				if (_mic != null) {
+					if (_mic.muted) {
 						var nc:NetConnection = new NetConnection();
 						nc.connect(null);
 						var ns:NetStream = new NetStream(nc);
-						ns.attachAudio(mic);
-						mic.addEventListener(StatusEvent.STATUS, function (event:StatusEvent):void {
+						ns.attachAudio(_mic);
+						_mic.addEventListener(StatusEvent.STATUS, function (event:StatusEvent):void {
 							debug("micStatusHandler! " + event);
-							mic.removeEventListener(StatusEvent.STATUS, arguments.callee);
+							_mic.removeEventListener(StatusEvent.STATUS, arguments.callee);
 							ns.close();
 							nc.close();
-							if (mic.muted) {
+							if (_mic.muted) {
 								debug("Unable to connect to active microphone.");
+							} else {
+								ExternalInterface.call("VideoSettings.allowRec", true);
 							}
 						});
 					}
@@ -257,39 +247,39 @@
 		}
 
 		private function startTestRecording():void {
-			var counter:int = 5;
-			timerText.visible = true;
-			timerText.text = "5 sec";
-			var recTimer:Timer = new Timer(1000, counter);
-			var t:Date = new Date();
-			recName = "TEST_SETUP_" + t.getTime();
-			var mic:Microphone = getMic();
-			video.record(recName, getCam(), mic, function ():void {
-				mic.addEventListener(ActivityEvent.ACTIVITY, micActivityHandler);
-				//mic.onA
-				var micTimer:Timer = new Timer(100, 0);
-				micTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
-					//FIXME TODO fill.width = mic.activityLevel * RIGHT_WIDTH / 100;
-					debug("activity: " + mic.activityLevel);
+			try {
+				var counter:int = 5;
+				timerText.visible = true;
+				timerText.text = "5 sec";
+				var recTimer:Timer = new Timer(1000, counter);
+				var t:Date = new Date();
+				recName = "TEST_SETUP_" + t.getTime();
+				mic = getMic();
+				var activityTimer:Timer = new Timer(100);
+				activityTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
+					ExternalInterface.call("VideoSettings.micActivity", mic.activityLevel);
 				});
-				recTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
-					timerText.text = --counter + " sec";
-					if (counter == 0) {
-						timerText.visible = false;
-						playTestRecording();
-						micTimer.stop();
-						mic.removeEventListener(ActivityEvent.ACTIVITY, micActivityHandler);
+				video.record(recName, getCam(), mic, function ():void {
+					if (mic != null) {
+						activityTimer.start();
 					}
+					recTimer.addEventListener(TimerEvent.TIMER, function (event:TimerEvent):void {
+						timerText.text = --counter + " sec";
+						if (counter == 0) {
+							timerText.visible = false;
+							ExternalInterface.call("VideoSettings.allowPlay");
+							playTestRecording();
+							activityTimer.stop();
+							mic = null;
+						}
+					});
+					recTimer.start();
 				});
-				recTimer.start();
-				micTimer.start();
-			});
-		}
-
-		private function micActivityHandler(event:ActivityEvent):void {
-			//Do nothing, it just need to be there.
+			} catch (err:Error) {
+				debug("ERROR: " + err);
+			}
 		}
-	]]></fx:Script>
+		]]></fx:Script>
 
 	<mx:UIComponent id="videoDisplay" width="0" height="0" />
 	<s:Label id="timerText" height="20" width="45" x="20" y="5" paddingLeft="5" paddingTop="5"

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
index 229911c..23eabbe 100644
--- a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
+++ b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
@@ -19,6 +19,7 @@
 package org.apache.openmeetings {
 import flash.events.AsyncErrorEvent;
 import flash.events.NetStatusEvent;
+import flash.external.ExternalInterface;
 import flash.media.Camera;
 import flash.media.H264Level;
 import flash.media.H264Profile;
@@ -43,13 +44,12 @@ public class OmVideo {
 	public var width:int;
 	public var height:int;
 	private var mode:String;
-	private var codec:String;
-	private var url:String;
+	private var params:Object;
+	private var fallback:Boolean;
 
-	public function OmVideo(ui:UIComponent, codec:String, url:String) {
+	public function OmVideo(ui:UIComponent, params:Object) {
 		this.ui = ui;
-		this.codec = codec;
-		this.url = url;
+		this.params = params;
 	}
 
 	private function getVideo():Video {
@@ -84,44 +84,42 @@ public class OmVideo {
 		vid = null;
 	}
 
+	private function debug(... rest):void {
+		ExternalInterface.call("console.log", rest);
+	}
+
 	private function createStream():void {
+		debug("createStream: ");
 		ns = new NetStream(nc);
 		//see: http://livedocs.adobe.com/flash/9.0_de/ActionScriptLangRefV3/flash/net/NetStream.html
 		//according to the docs the construct to catch event has to be implemented like this.
 		//var t = this;
-		var clientObject:Object = new Object();
-		clientObject.onMetaData = function(metadata:Object):void {
-			//t.onMetaData(metadata);
-			trace("onMetaData: ", metadata);
-		};
-		clientObject.onPlayStatus = function(metadata:Object):void {
-			//t.onPlayStatus(metadata);
-			trace("onPlayStatus: ", metadata);
-		};
-		clientObject.onCuePoint = function(metadata:Object):void {
-			//t.onCuePoint(metadata);
-			trace("onCuePoint: ", metadata);
-		};
-		clientObject.ioError = function(error:Object):void {
-			//t.ioError(error);
-			trace("ioError: ", error);
-		};
-		clientObject.netStatus = function(status:Object):void {
-			//t.netStatus(status);
-			trace("netStatus: ", status);
-		};
-		clientObject.asyncError = function(error:Object):void {
-			//t.asyncError(error);
-			trace("asyncError: ", error);
+		ns.client = {
+			onMetaData: function(metadata:Object):void {
+				debug("onMetaData: ", metadata);
+			}
+			, onPlayStatus: function(metadata:Object):void {
+				debug("onPlayStatus: ", metadata);
+			}
+			, onCuePoint: function(metadata:Object):void {
+				debug("onCuePoint: ", metadata);
+			}
+			, ioError: function(error:Object):void {
+				debug("ioError: ", error);
+			}
+			, netStatus: function(status:Object):void {
+				debug("netStatus: ", status);
+			}
+			, asyncError: function(error:Object):void {
+				debug("asyncError: ", error);
+			}
 		};
-		ns.client = clientObject;
 		//this is a workaround, attaching the event to the client object does not work
 		ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus2);
 	}
 
 	private function onNetStatus2(evt:Object):void {
-		trace("netStream_onNetStatus: ", evt.info.code, evt.target);
-		//this.onNetStatus.sendEvent(evt.info);
+		debug("netStream_onNetStatus: ", evt.info.code, evt.target);
 	}
 
 	private function _publish(mode:String, name:String, cam:Camera, mic:Microphone, f:Function):void {
@@ -137,8 +135,8 @@ public class OmVideo {
 			attachCamera(cam);
 
 			var videoStreamSettings:VideoStreamSettings = null;
-			trace("codec = " + codec);
-			if (codec === CODEC_H264) {
+			debug("codec = " + params.videoCodec);
+			if (params.videoCodec === CODEC_H264) {
 				var vss:H264VideoStreamSettings = new H264VideoStreamSettings();
 				vss.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_5_1);
 				videoStreamSettings = vss;
@@ -147,7 +145,7 @@ public class OmVideo {
 			}
 			videoStreamSettings.setQuality(cam.bandwidth, cam.quality);
 			videoStreamSettings.setKeyFrameInterval(cam.keyFrameInterval);
-			trace("::keyFrameInterval " + cam.keyFrameInterval);
+			debug("::keyFrameInterval " + cam.keyFrameInterval);
 			videoStreamSettings.setMode(cam.width, cam.height, cam.fps);
 			ns.videoStreamSettings = videoStreamSettings;
 		}
@@ -162,12 +160,22 @@ public class OmVideo {
 		}
 	}
 
+	private function getUrl():String {
+		var secure:Boolean = ('true' === params.secure);
+		var url:String = (secure ? "rtmps" : "rtmp") + "://"
+				+ params.host + ":" + (secure ? params.rtmpsPort : params.rtmpPort)
+				+ "/" + params.app;
+		//TODO fallback
+		return url;
+	}
+
 	private function publish(mode:String, name:String, cam:Camera, mic:Microphone, f:Function):void {
 		if (nc == null || !nc.connected) {
-			trace("NetConnection is not connected");
+			var url:String = getUrl();
+			debug("NetConnection is not connected", url);
 			nc = new NetConnection();
 			nc.addEventListener(NetStatusEvent.NET_STATUS, function onConnectionStatus(e:NetStatusEvent):void {
-				trace("ConnectionStatus: " + e.info.code);
+				debug("ConnectionStatus: " + e.info.code);
 				if (e.info.code == "NetConnection.Connect.Success") {
 					_publish(mode, name, cam, mic, f);
 				} else {
@@ -175,26 +183,28 @@ public class OmVideo {
 				}
 			});
 			nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, function (event:AsyncErrorEvent):void {
-				trace("login Async error" + event);
+				debug("login Async error" + event);
 			});
 			nc.client = {
 				onMetaData: function (infoObject:Object):void {
-					for (var propName:String in infoObject) {
-						trace(propName + " = " + infoObject[propName]);
-					}
+					debug("onMetaData::", infoObject);
 				}
 				, onBWDone: function(...rest):void {
-					trace("onBWDone");
+					debug("onBWDone");
 				}
 				, onBWCheck: function(...rest):Number {
-					trace("onBWCheck");
+					debug("onBWCheck");
 					return 0;
 				}
 				, setId: function (id:Number):void {
-					trace("id: " + id); //TODO save connection id
+					debug("id: " + id); //TODO save connection id
 				}
 			};
-			nc.connect(url);
+			nc.connect(url, {
+				uid: params.uid
+				, sid: params.sid
+				, nativeSsl: 'best' == params.proxyType
+			});
 		} else {
 			_publish(mode, name, cam, mic, f);
 		}
@@ -205,6 +215,7 @@ public class OmVideo {
 	}
 
 	public function play(name:String):void {
+		debug("PLAY::", name);
 		if (ns != null){
 			reset();
 		}
@@ -215,16 +226,15 @@ public class OmVideo {
 		//FIXME: Commented out, cause this leads to Buffer-Full/Buffer-Empty Events
 		//after re-syncing the stream
 		//this.setBuffer(0.1);
-		ns.play(name);
+		ns.play(name + ".flv");
 	}
 
 	public function reset():void {
-		var vid:Video = getVideo();
 		if (ns != null) {
 			switch (mode) {
 				case PLAY:
 					ns.pause();
-					ns.close();
+					ns.dispose();
 					clear();
 					break;
 				case BROADCAST:
@@ -232,7 +242,7 @@ public class OmVideo {
 					ns.publish(null); //false in original code
 				default:
 					clear();
-					ns.close();
+					ns.dispose();
 					break;
 			}
 		} else {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
----------------------------------------------------------------------
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
index 1ceabe0..8ec1230 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
@@ -34,6 +34,10 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_LDAP_ID;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DOCUMENT_DPI;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DOCUMENT_QUALITY;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE_PROXY;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_VIDEO_CODEC;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_VIDEO_FPS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FRONTEND_REGISTER_KEY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_GOOGLE_ANALYTICS_CODE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_IGNORE_BAD_SSL;
@@ -352,6 +356,10 @@ public class ImportInitvalues {
 				"Users entered the room via invitationHash or secureHash will be redirected to this URL on connection lost");
 		cfgDao.add(CONFIG_CALENDAR_FIRST_DAY, "0", null, "The day that each week begins. The value must be a number that represents the day of the week. Sunday=0, Monday=1, Tuesday=2, etc.");
 		cfgDao.add(CONFIG_GOOGLE_ANALYTICS_CODE, null, null, "Code for Google Analytics");
+		cfgDao.add(CONFIG_FLASH_SECURE, "no", null, "Wether it should try to connect to rtmps first or not\nValid values: yes / no");
+		cfgDao.add(CONFIG_FLASH_SECURE_PROXY, "none", null, "The setting for the NetConnection default settings is 'none'\n set to value 'best' if you are trying to use rtmp over native SSL");
+		cfgDao.add(CONFIG_FLASH_VIDEO_CODEC, "h263", null, "Camera codecType, possible values: 'h263', 'h264'");
+		cfgDao.add(CONFIG_FLASH_VIDEO_FPS, "30", null, "Camera FPS, should be positive number in range (0, 60]");
 
 		log.debug("Configurations ADDED");
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
----------------------------------------------------------------------
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
index 314bd51..f7b6c35 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
@@ -51,6 +51,10 @@ public class OpenmeetingsVariables {
 	public static final String CONFIG_IMAGEMAGIC_PATH = "imagemagick_path";
 	public static final String CONFIG_DOCUMENT_DPI = "document.dpi";
 	public static final String CONFIG_DOCUMENT_QUALITY = "document.quality";
+	public static final String CONFIG_FLASH_SECURE = "flash.secure";
+	public static final String CONFIG_FLASH_SECURE_PROXY = "flash.secure.proxy";
+	public static final String CONFIG_FLASH_VIDEO_CODEC = "flash.video.codec";
+	public static final String CONFIG_FLASH_VIDEO_FPS = "flash.video.fps";
 	public static final String MENU_ROOMS_NAME = "Conference Rooms";
 	public static final int RECENT_ROOMS_COUNT = 5;
 	public static final int LEVEL_USER = 1;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.html
index d1e8471..cbd175c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInDialog.html
@@ -16,12 +16,9 @@
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-  
+
 -->
 <html xmlns:wicket="http://wicket.apache.org">
-<wicket:head>
-	<script type="text/javascript" src="js/openmeetings_functions.js"></script>
-</wicket:head>
 <wicket:panel>
 	<form wicket:id="signin" class="signin">
 		<table>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizardPage.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizardPage.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizardPage.html
index df874bf..1a9041b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizardPage.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/install/InstallWizardPage.html
@@ -7,20 +7,19 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-  
+
       http://www.apache.org/licenses/LICENSE-2.0
-    	  
+
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-  
+
 -->
 <html xmlns:wicket="http://wicket.apache.org">
 <wicket:head>
-	<script type="text/javascript" src="js/openmeetings_functions.js" ></script>
 	<style type="text/css">
 		.abstractWizard .adminForm div.formelement {
 			max-width: 600px;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index a479791..b05150f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -36,6 +36,7 @@ import java.util.Set;
 import java.util.UUID;
 
 import org.apache.directory.api.util.Strings;
+import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
 import org.apache.openmeetings.db.dao.log.ConferenceLogDao;
@@ -123,14 +124,12 @@ public class RoomPanel extends BasePanel {
 				String path = url.getPath();
 				path = path.substring(1, path.indexOf('/', 2) + 1);
 				ClientProperties cp = WebSession.get().getClientInfo().getProperties();
-				target.appendJavaScript(String.format("VideoSettings.init(%s);", new JSONObject()
+				target.appendJavaScript(String.format("VideoSettings.init(%s);", new JSONObject(getBean(ScopeApplicationAdapter.class).getFlashSettings().toString())
 						.put("uid", getClient().getUid())
 						.put("audioOnly", r.isAudioOnly())
 						.put("SID", WebSession.getSid())
 						.put("interview", Room.Type.interview == r.getType())
-						//.put("protocol", cfgDao.getConfValue(CONFIG_FLASH_PROTOCOL, String.class, ""))
 						.put("host", url.getHost())
-						//.put("port", cfgDao.getConfValue(CONFIG_FLASH_PORT, String.class, ""))
 						.put("app", path + r.getId())
 						.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct")
 						.toString()

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
index 255040c..d98dd4b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
@@ -79,7 +79,6 @@ public class SwfPanel extends BasePanel {
 	public void renderHead(IHeaderResponse response) {
 		super.renderHead(response);
 		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(newResourceReference())));
-		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forUrl("js/openmeetings_functions.js")));
 		response.render(OnDomReadyHeaderItem.forScript(panelLoaded.getCallbackScript()));
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index c9109a2..1e2c563 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -93,7 +93,8 @@ function startPrivateChat(el) {
 	$('#chatMessage .wysiwyg-editor').click();
 }
 var VideoSettings = (function() {
-	var self = {}, vs, lm, swf, s, cam, mic, res, inited = false;
+	var self = {}, vs, lm, swf, s, cam, mic, res,
+		vidScroll, recBtn, playBtn, inited = false, recAllowed = false;
 	function _load() {
 		s = {};
 		try {
@@ -112,6 +113,14 @@ var VideoSettings = (function() {
 		cam = vs.find('select.cam');
 		mic = vs.find('select.mic');
 		res = vs.find('select.cam-resolution');
+		vidScroll = vs.find('.vid-block .video-conainer');
+		recBtn = vs.find('.rec-start').click(function() {
+			recBtn.prop('disabled', true).button('refresh'); //TODO disable drop-downs
+			swf.startRec();
+		});
+		playBtn = vs.find('.play').click(function() {
+			swf.play();
+		});
 		vs.dialog({
 			classes: {
 				'ui-dialog': 'ui-corner-all video'
@@ -140,18 +149,43 @@ var VideoSettings = (function() {
 		lm.progressbar({ value: 0 });
 		options.width = 300;
 		options.height = 200;
-		swf = initVideo(vs.find('.vid-block .video-conainer'), 'video-settings-swf', options)[0];
+		swf = initVideo(vidScroll, 'video-settings-swf', options)[0];
 		vs.find('input, button').prop('disabled', true);
 		vs.find('button').button();
+		var rr = vs.find('.cam-resolution').parent('.sett-row');
+		if (!!options.interview) {
+			rr.show();
+		} else {
+			rr.hide();
+		}
 		_load();
 	}
+	function _updateRec() {
+		recBtn.prop('disabled', !recAllowed && (s.video.cam > -1 || s.video.mic > -1)).button('refresh');
+	}
 	function _readValues() {
-		s.video.cam = cam.val();
-		s.video.mic = mic.val();
+		s.video.cam = 1 * cam.val();
+		s.video.mic = 1 * mic.val();
 		var o = res.find('option:selected').data();
 		s.video.width = o.width;
 		s.video.height = o.height;
 		$(swf).attr('width', Math.max(300, s.video.width)).attr('height', Math.max(200, s.video.height));
+		vidScroll.scrollLeft(Math.max(0, s.video.width / 2 - 150))
+			.scrollTop(Math.max(0, s.video.height / 2 - 110));
+		_updateRec();
+	}
+	
+	function _allowRec(allow) {
+		recAllowed = allow;
+		_updateRec();
+	}
+	function _allowPlay() {
+		_updateRec();
+		playBtn.prop('disabled', false).button('refresh');
+	}
+	function _micActivity(level) {
+		console.log("activity: ", level)
+		lm.progressbar("value", Math.max(0, level));
 	}
 	function _initSwf() {
 		if (!inited) {
@@ -193,19 +227,17 @@ var VideoSettings = (function() {
 		_readValues();
 		swf.init(s.video.cam, s.video.mic, s.video.width, s.video.height);
 	}
-	function _open(interview) {
-		var rr = vs.find('.cam-resolution').parent('.sett-row');
-		if (interview) {
-			rr.show();
-		} else {
-			rr.hide();
-		}
+	function _open() {
+		recAllowed = false;
 		vs.dialog('open');
 	}
 	return {
 		init: _init
 		, initSwf: _initSwf
 		, open: _open
+		, allowRec: _allowRec
+		, allowPlay: _allowPlay
+		, micActivity: _micActivity
 		, close: function() { vs.dialog('close'); }
 	};
 })();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
index 56a41c1..5809dcd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
@@ -88,14 +88,14 @@
 					</div>
 				</div>
 				<div class="sett-row right">
-					<div><button><wicket:message key="775"/></button></div>
+					<div><button class="rec-start"><wicket:message key="775"/></button></div>
 				</div>
 			</div>
 			<div class="vid-block">
 				<div class="video-conainer"></div>
 				<div class="level-meter"></div>
 				<div class="sett-row right">
-					<div><button><wicket:message key="764"/></button></div>
+					<div><button class="play"><wicket:message key="764"/></button></div>
 				</div>
 			</div>
 		</div>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8599b3df/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
index 0c9f020..ab60687 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
@@ -19,7 +19,6 @@
 package org.apache.openmeetings.web.room.sidebar.icon;
 
 import org.apache.openmeetings.db.entity.basic.Client;
-import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.web.room.RoomPanel;
 
 public class SettingsIcon extends ClientIcon {
@@ -42,6 +41,6 @@ public class SettingsIcon extends ClientIcon {
 
 	@Override
 	protected String getScript() {
-		return String.format("VideoSettings.open(%s);", Room.Type.interview == room.getRoom().getType());
+		return String.format("VideoSettings.open();");
 	}
 }


[02/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] presentation drop is implemented, other types broken

Posted by so...@apache.org.
[OPENMEETINGS-551] presentation drop is implemented, other types broken


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/aaab149b
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/aaab149b
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/aaab149b

Branch: refs/heads/master
Commit: aaab149bef393a76df009204b6d2fbc20cf6cc5e
Parents: e30de20
Author: Maxim Solodovnik <so...@apache.org>
Authored: Fri Mar 31 18:17:02 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Fri Mar 31 18:17:02 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/web/room/wb/WbPanel.html       |   4 +-
 .../openmeetings/web/room/wb/WbPanel.java       |   5 +
 .../org/apache/openmeetings/web/room/wb/wb.js   | 290 +++++++++++--------
 openmeetings-web/src/main/webapp/css/room.css   |  10 +-
 4 files changed, 186 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/aaab149b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
index e48268f..c0a8ddc 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
@@ -50,7 +50,9 @@
 		</div>
 		
 		<div id="wb-area">
-			<div class="canvases"></div>
+			<div class="scroll-container">
+				<div class="canvases"></div>
+			</div>
 			<div class="tools ui-state-active vertical clear" style="position: absolute; top: 20px; right: 0px;">
 				<div class="bumper"></div>
 				<div wicket:message="title:72" class="ui-widget-header clickable om-icon big pointer"></div>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/aaab149b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index b05d325..a292000 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -302,6 +302,11 @@ public class WbPanel extends Panel {
 				file.put("_src", urlFor(ref, pp));
 				file.put("_poster", urlFor(new JpgRecordingResourceReference(), pp));
 				break;
+			case Presentation:
+				ref = new RoomResourceReference();
+				file.put("_src", urlFor(ref, pp));
+				file.put("deleted", !fi.exists());
+				break;
 			default:
 				ref = new RoomResourceReference();
 				file.put("src", urlFor(ref, pp));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/aaab149b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index 71718e8..4952f58 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -44,6 +44,7 @@ var Base = function() {
 	var base = {};
 	base.objectCreated = function(o, canvas) {
 		o.uid = UUID.generate();
+		o.slide = canvas.slide;
 		canvas.trigger("wb:object:created", o);
 		return o.uid;
 	}
@@ -481,7 +482,7 @@ var Clipart = function(wb, btn) {
 }
 var Wb = function() {
 	const ACTIVE = 'active';
-	var wb = {id: -1}, a, t, s, canvases = [], mode, slide = 0;
+	var wb = {id: -1}, a, t, s, canvases = [], mode, slide = 0, resizable = true;
 
 	function getBtn(m) {
 		return t.find(".om-icon." + (m || mode));
@@ -624,9 +625,90 @@ var Wb = function() {
 			}
 		});
 	}
+	function _findObject(o) {
+		var _o = {};
+		canvases[o.slide].forEachObject(function(__o) {
+			if (!!__o && o.uid === __o.uid) {
+				_o = __o;
+				return false;
+			}
+		});
+		return _o;
+	}
+	function _removeHandler(o) {
+		var __o = _findObject(o);
+		if (!!__o) {
+			canvases[o.slide].remove(__o);
+		}
+	}
+	function _modifyHandler(_o) {
+		_removeHandler(_o);
+		canvases[_o.slide].add(_o);
+	}
+	function _createHandler(_o) {
+		switch (_o.fileType) {
+			case 'Video':
+			case 'Recording':
+			{
+				var vid = $('<video>').hide().attr('id', 'video-' + _o.uid).attr('poster', _o._poster + '&preview=true')
+					.attr("width", _o.width).attr("height", _o.height)
+					.append($('<source>').attr('type', 'video/mp4').attr('src', _o._src))
+				$('#wb-tab-' + canvas.wbId).append(vid);
+				var vImg = new fabric.Image(vid[0], {
+					left: _o.left
+					, top: _o.top
+				});
+				canvases[_o.slide].add(vImg);
+				//console.log(vImg.toJSON(['uid', 'fileId', 'fileType']));
+			}
+				break;
+			case 'Presentation':
+			{
+				if (resizable && !_o.deleted) {
+					resizable = false;
+				}
+				var count = _o.deleted ? 1 : _o.count;
+				for (var i = 0; i < count; ++i) {
+					if (canvases.length < i + 1) {
+						addCanvas();
+					}
+					var canvas = canvases[i];
+					/*
+					 * TODO block resizing
+					*/
+					canvas.setBackgroundImage(_o._src + "&slide=" + i, canvas.renderAll.bind(canvas), {
+						/*backgroundImageOpacity: 0.5
+						, */backgroundImageStretch: false
+					}).setWidth(Math.max(canvas.width, _o.width)).setHeight(Math.max(canvas.height, _o.height));
+				}
+			}
+				break;
+			default:
+				canvases[_o.slide].add(_o);
+				break;
+		}
+	}
+	function _createObject(arr, handler) {
+		fabric.util.enlivenObjects(arr, function(objects) {
+			wb.eachCanvas(function(canvas) {
+				canvas.renderOnAddRemove = false;
+			});
+
+			for (var i = 0; i < objects.length; ++i) {
+				var _o = objects[i];
+				_o.loaded = true;
+				handler(_o);
+			}
+
+			wb.eachCanvas(function(canvas) {
+				canvas.renderOnAddRemove = true;
+				canvas.renderAll();
+			});
+		});
+	};
 
 	function toOmJson(o) {
-		return o.toJSON(['uid', 'fileId', 'fileType', 'count']);
+		return o.toJSON(['uid', 'fileId', 'fileType', 'count', 'slide']);
 	}
 	//events
 	function wbObjCreatedHandler(o) {
@@ -651,6 +733,7 @@ var Wb = function() {
 		switch(o.type) {
 			case 'i-text':
 				o.uid = UUID.generate();
+				o.slide = this.slide;
 				wbObjCreatedHandler(o);
 				break;
 		}
@@ -672,6 +755,7 @@ var Wb = function() {
 	}
 	function pathCreatedHandler(o) {
 		o.path.uid = UUID.generate();
+		o.path.slide = this.slide;
 		wbObjCreatedHandler(o.path);
 	};
 	/*TODO interactive text chage
@@ -684,11 +768,12 @@ var Wb = function() {
 		console.log('Text Changed', obj);
 	};*/
 	function addCanvas() {
-		var c = $('<canvas></canvas>').attr('id', 'can-' + a.attr('id'));
+		var slide = canvases.length;
+		var c = $('<canvas></canvas>').attr('id', 'can-' + a.attr('id') + '-slide-' + slide);
 		a.find('.canvases').append(c);
 		var canvas = new fabric.Canvas(c.attr('id'));
 		canvas.wbId = wb.id;
-		canvas.slide = canvases.length;
+		canvas.slide = slide;
 		//TODO create via WS canvas:cleared
 		canvas.on({
 			'object:added': objAddedHandler
@@ -717,9 +802,58 @@ var Wb = function() {
 				, collision: "fit"
 			});
 		}
-		wb.eachCanvas(function(canvas) {
-			canvas.setWidth(w).setHeight(h);
-		});
+		if (resizable) {
+			//TODO FIXME need to be checked
+			wb.eachCanvas(function(canvas) {
+				canvas.setWidth(w).setHeight(h);
+			});
+		}
+	};
+	wb.load = function(arr) {
+		_createObject(arr, _createHandler);
+	};
+	wb.createObj = function(o) {
+		switch(o.type) {
+			case 'pointer':
+				APointer().create(canvases[o.slide], o);
+				break;
+			default:
+				_createObject([o], _createHandler);
+				/*
+				 * https://jsfiddle.net/l2aelba/kro7h6rv/2/
+				if ('Video' === o.fileType || 'Recording' === o.fileType) {
+					fabric.util.requestAnimFrame(function render() {
+						canvas.renderAll();
+						fabric.util.requestAnimFrame(render);
+					});
+				}
+				*/
+				break;
+		}
+	};
+	wb.modifyObj = function(o) { //TODO need to be unified
+		switch(o.type) {
+			case 'pointer':
+				_modifyHandler(APointer().create(canvases[o.slide], o))
+				break;
+			default:
+				var arr = [o];
+				if (!!o.objects) {
+					arr = o.objects;
+					for (var i = 0; i < arr.length; ++i) {
+						var _o = arr[i];
+						_o.left += o.left;
+						_o.top += o.top;
+					}
+				}
+				_createObject(o.objects || [o], _modifyHandler);
+				break;
+		}
+	};
+	wb.removeObj = function(arr) {
+		for (var i = 0; i < arr.length; ++i) {
+			_removeHandler(arr[i]);
+		}
 	};
 	wb.getCanvas = function() {
 		return canvases[slide];
@@ -752,20 +886,28 @@ var WbArea = (function() {
 			case 8:  // backspace
 			case 46: // delete
 				{
-					var wb = getActive();
-					var canvas = wb.data('getCanvas')();
+					var wb = getActive().data();
+					var canvas = wb.getCanvas();
 					if (!!canvas) {
 						var arr = [];
 						if (canvas.getActiveGroup()) {
-							canvas.getActiveGroup().forEachObject(function(o){ arr.push(o.uid); });
+							canvas.getActiveGroup().forEachObject(function(o){
+								arr.push({
+									uid: o.uid
+									, slide: o.slide
+								});
+							});
 						} else {
 							var obj = canvas.getActiveObject();
 							if (!!obj) {
-								arr.push(obj.uid);
+								arr.push({
+									uid: o.uid
+									, slide: o.slide
+								});
 							}
 						}
 						wbAction('deleteObj', JSON.stringify({
-							wbId: wb.data('id')()
+							wbId: wb.id
 							, obj: arr
 						}));
 						return false;
@@ -774,64 +916,6 @@ var WbArea = (function() {
 				break;
 		}
 	}
-	function _removeHandler(canvas, _uid) {
-		var __o = _findObject(canvas, _uid);
-		if (!!__o) {
-			canvas.remove(__o);
-		}
-	}
-	function _modifyHandler(canvas, _o) {
-		_removeHandler(canvas, _o.uid);
-		canvas.add(_o);
-	}
-	function _createHandler(canvas, _o) {
-		switch (_o.fileType) {
-			case 'Video':
-			case 'Recording':
-			{
-				var vid = $('<video>').hide().attr('id', 'video-' + _o.uid).attr('poster', _o._poster + '&preview=true')
-					.attr("width", _o.width).attr("height", _o.height)
-					.append($('<source>').attr('type', 'video/mp4').attr('src', _o._src))
-				$('#wb-tab-' + canvas.wbId).append(vid);
-				var vImg = new fabric.Image(vid[0], {
-					left: _o.left
-					, top: _o.top
-				});
-				canvas.add(vImg);
-				//console.log(vImg.toJSON(['uid', 'fileId', 'fileType']));
-			}
-				break;
-			case 'Presentation':
-			default:
-				canvas.add(_o);
-				break;
-		}
-	}
-	function _findObject(canvas, uid) {
-		var _o = {};
-		canvas.forEachObject(function(__o) {
-			if (!!__o && uid === __o.uid) {
-				_o = __o;
-				return false;
-			}
-		});
-		return _o;
-	}
-	function _createObject(canvas, arr, handler) {
-		fabric.util.enlivenObjects(arr, function(objects) {
-			var origRenderOnAddRemove = canvas.renderOnAddRemove;
-			canvas.renderOnAddRemove = false;
-
-			for (var i = 0; i < objects.length; ++i) {
-				var _o = objects[i];
-				_o.loaded = true;
-				handler(canvas, _o);
-			}
-
-			canvas.renderOnAddRemove = origRenderOnAddRemove;
-			canvas.renderAll();
-		});
-	}
 	function _activateTab(wbId) {
 		container.find('.wb-tabbar li').each(function(idx) {
 			if (wbId == 1 * $(this).data('wb-id')) {
@@ -844,11 +928,11 @@ var WbArea = (function() {
 	self.getWbTabId = function(id) {
 		return "wb-tab-" + id;
 	};
-	self.getCanvas = function(id) {
-		return $('#' + self.getWbTabId(id)).data('getCanvas')();
+	self.getWb = function(id) {
+		return $('#' + self.getWbTabId(id)).data();
 	};
-	self.eachCanvas = function(id, func) {
-		return $('#' + self.getWbTabId(id)).data('eachCanvas')(func);
+	self.getCanvas = function(id) {
+		return self.getWb(id).getCanvas();
 	};
 	self.init = function() {
 		container = $(".room.wb.area");
@@ -892,7 +976,9 @@ var WbArea = (function() {
 		tabs.append(wb);
 		refreshTabs();
 	
-		wb.data(Wb()).data('init')(obj.id, tid);
+		var wbo = Wb();
+		wb.data(wbo);
+		wbo.init(obj.id, tid);
 	}
 	self.add = function(obj) {
 		self.create(obj);
@@ -902,55 +988,16 @@ var WbArea = (function() {
 		_activateTab(obj.id);
 	}
 	self.load = function(json) {
-		_createObject(self.getCanvas(json.wbId), json.obj, _createHandler);
+		self.getWb(json.wbId).load(json.obj);
 	};
-	self.createObj = function(json) { //TODO need to be unified
-		var canvas = self.getCanvas(json.wbId);
-		var o = json.obj;
-		switch(o.type) {
-			case 'pointer':
-				APointer().create(canvas, o);
-				break;
-			default:
-				_createObject(canvas, [o], _createHandler);
-				/*
-				 * https://jsfiddle.net/l2aelba/kro7h6rv/2/
-				if ('Video' === o.fileType || 'Recording' === o.fileType) {
-					fabric.util.requestAnimFrame(function render() {
-						canvas.renderAll();
-						fabric.util.requestAnimFrame(render);
-					});
-				}
-				*/
-				break;
-		}
+	self.createObj = function(json) {
+		self.getWb(json.wbId).createObj(json.obj);
 	};
-	self.modifyObj = function(json) { //TODO need to be unified
-		var canvas = self.getCanvas(json.wbId);
-		var o = json.obj;
-		switch(o.type) {
-			case 'pointer':
-				_modifyHandler(canvas, APointer().create(canvas, o))
-				break;
-			default:
-				var arr = [o];
-				if (!!o.objects) {
-					arr = o.objects;
-					for (var i = 0; i < arr.length; ++i) {
-						var _o = arr[i];
-						_o.left += o.left;
-						_o.top += o.top;
-					}
-				}
-				_createObject(canvas, o.objects || [o], _modifyHandler);
-				break;
-		}
+	self.modifyObj = function(json) {
+		self.getWb(json.wbId).modifyObj(json.obj);
 	};
 	self.removeObj = function(json) {
-		var canvas = self.getCanvas(json.wbId);
-		for (var i = 0; i < json.obj.length; ++i) {
-			_removeHandler(canvas, json.obj[i]);
-		}
+		self.getWb(json.wbId).removeObj(json.obj);
 	};
 	self.remove = function(obj) {
 		var tabId = self.getWbTabId(obj.id);
@@ -970,8 +1017,9 @@ var WbArea = (function() {
 		var wbah = hh - 5 - wbTabs.find("ul.ui-tabs-nav").height();
 		tabPanels.height(wbah);
 		tabPanels.each(function(idx) {
-			$(this).data('resize')(w, wbah);
+			$(this).data('resize')(w - 20, wbah);
 		});
+		wbTabs.find(".ui-tabs-panel .scroll-container").height(wbah);
 	}
 	return self;
 })();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/aaab149b/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index dcad44c..3b6a9ea 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -501,4 +501,12 @@
 	height: 20px;
 	padding: 0;
 }
-
+.wb-area .ui-tabs-panel .scroll-container {
+	overflow: auto;
+}
+.wb-area .ui-tabs-panel .scroll-container .canvas-container {
+	margin-top: 5px;
+	margin-left: 5px;
+	border: 1px solid #888888;
+	box-shadow: 5px 5px 5px #888888;
+}


[30/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] screen-sharing is displayed in room

Posted by so...@apache.org.
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
deleted file mode 100644
index f0e5db7..0000000
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
+++ /dev/null
@@ -1,1750 +0,0 @@
-/*
- * 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.core.remote.red5;
-
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE_PROXY;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_VIDEO_CODEC;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.openmeetings.IApplication;
-import org.apache.openmeetings.core.data.conference.RoomManager;
-import org.apache.openmeetings.core.remote.RecordingService;
-import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
-import org.apache.openmeetings.core.util.WebSocketHelper;
-import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
-import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
-import org.apache.openmeetings.db.dao.label.LabelDao;
-import org.apache.openmeetings.db.dao.log.ConferenceLogDao;
-import org.apache.openmeetings.db.dao.record.RecordingDao;
-import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.dao.server.ISessionManager;
-import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.dao.server.SessiondataDao;
-import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.dto.room.BrowserStatus;
-import org.apache.openmeetings.db.dto.room.RoomStatus;
-import org.apache.openmeetings.db.entity.log.ConferenceLog;
-import org.apache.openmeetings.db.entity.room.Client;
-import org.apache.openmeetings.db.entity.room.Room;
-import org.apache.openmeetings.db.entity.room.Room.RoomElement;
-import org.apache.openmeetings.db.entity.server.Server;
-import org.apache.openmeetings.db.entity.server.Sessiondata;
-import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.util.AuthLevelUtil;
-import org.apache.openmeetings.util.CalendarPatterns;
-import org.apache.openmeetings.util.InitializationContainer;
-import org.apache.openmeetings.util.OmFileHelper;
-import org.apache.openmeetings.util.OpenmeetingsVariables;
-import org.apache.openmeetings.util.Version;
-import org.apache.openmeetings.util.message.RoomMessage;
-import org.apache.openmeetings.util.message.TextRoomMessage;
-import org.apache.wicket.Application;
-import org.apache.wicket.util.string.StringValue;
-import org.apache.wicket.util.string.Strings;
-import org.red5.logging.Red5LoggerFactory;
-import org.red5.server.adapter.MultiThreadedApplicationAdapter;
-import org.red5.server.api.IClient;
-import org.red5.server.api.IConnection;
-import org.red5.server.api.Red5;
-import org.red5.server.api.scope.IBasicScope;
-import org.red5.server.api.scope.IBroadcastScope;
-import org.red5.server.api.scope.IScope;
-import org.red5.server.api.scope.ScopeType;
-import org.red5.server.api.service.IPendingServiceCall;
-import org.red5.server.api.service.IPendingServiceCallback;
-import org.red5.server.api.service.IServiceCapableConnection;
-import org.red5.server.api.stream.IBroadcastStream;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import com.github.openjson.JSONObject;
-
-public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter implements IPendingServiceCallback {
-	private static final Logger log = Red5LoggerFactory.getLogger(ScopeApplicationAdapter.class, webAppRootKey);
-	private static final String SECURITY_CODE_PARAM = "securityCode";
-	private static final String WIDTH_PARAM = "width";
-	private static final String HEIGHT_PARAM = "height";
-	public static final String FLASH_SECURE = "secure";
-	public static final String FLASH_NATIVE_SSL = "native";
-	public static final String FLASH_PORT = "rtmpPort";
-	public static final String FLASH_SSL_PORT = "rtmpsPort";
-	public static final String FLASH_VIDEO_CODEC = "videoCodec";
-	public static final String FLASH_FPS = "fps";
-
-	@Autowired
-	private ISessionManager sessionManager;
-	@Autowired
-	private RecordingService recordingService;
-	@Autowired
-	private ConfigurationDao cfgDao;
-	@Autowired
-	private AppointmentDao appointmentDao;
-	@Autowired
-	private SessiondataDao sessiondataDao;
-	@Autowired
-	private RoomManager roomManager;
-	@Autowired
-	private ConferenceLogDao conferenceLogDao;
-	@Autowired
-	private UserDao userDao;
-	@Autowired
-	private RoomDao roomDao;
-	@Autowired
-	private RecordingDao recordingDao;
-	@Autowired
-	private ServerDao serverDao;
-	private JSONObject flashSettings;
-
-	private static AtomicLong broadCastCounter = new AtomicLong(0);
-
-	@Override
-	public void resultReceived(IPendingServiceCall arg0) {
-		if (log.isTraceEnabled()) {
-			log.trace("resultReceived:: {}", arg0);
-		}
-	}
-
-	@Override
-	public boolean appStart(IScope scope) {
-		try {
-			OmFileHelper.setOmHome(scope.getResource("/").getFile());
-			LabelDao.initLanguageMap();
-
-			log.debug("webAppPath : " + OmFileHelper.getOmHome());
-
-			// Only load this Class one time Initially this value might by empty, because the DB is empty yet
-			getCryptKey();
-
-			// init your handler here
-			Properties props = new Properties();
-			try (InputStream is = new FileInputStream(new File(new File(OmFileHelper.getRootDir(), "conf"), "red5.properties"))) {
-				props.load(is);
-			}
-			flashSettings = new JSONObject()
-					.put(FLASH_SECURE, "yes".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE, String.class, "no")))
-					.put(FLASH_NATIVE_SSL, "best".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE_PROXY, String.class, "none")))
-					.put(FLASH_PORT, props.getProperty("rtmp.port"))
-					.put(FLASH_SSL_PORT, props.getProperty("rtmps.port"))
-					.put(FLASH_VIDEO_CODEC, cfgDao.getConfValue(CONFIG_FLASH_VIDEO_CODEC, String.class, "h263"))
-					.put(FLASH_FPS, cfgDao.getConfValue(OpenmeetingsVariables.CONFIG_FLASH_VIDEO_FPS, Integer.class, "30"))
-					;
-
-			for (String scopeName : scope.getScopeNames()) {
-				log.debug("scopeName :: " + scopeName);
-			}
-
-			InitializationContainer.initComplete = true;
-			Version.logOMStarted();
-			recordingDao.resetProcessingStatus(); //we are starting so all processing recordings are now errors
-			sessionManager.clearCache(); // 'sticky' clients should be cleaned up from DB
-		} catch (Exception err) {
-			log.error("[appStart]", err);
-		}
-		return true;
-	}
-
-	@SuppressWarnings("unchecked")
-	private static Map<String, Object> getConnParams(Object[] params) {
-		if (params != null && params.length > 0) {
-			return (Map<String, Object>)params[0];
-		}
-		return new HashMap<>();
-	}
-
-	@Override
-	public boolean roomConnect(IConnection conn, Object[] params) {
-		log.debug("roomConnect : ");
-
-		IServiceCapableConnection service = (IServiceCapableConnection) conn;
-		String streamId = conn.getClient().getId();
-
-		log.debug("### Client connected to OpenMeetings, register Client StreamId: " + streamId + " scope " + conn.getScope().getName());
-
-		// Set StreamId in Client
-		service.invoke("setId", new Object[] { streamId }, this);
-
-		Map<String, Object> map = conn.getConnectParams();
-		String swfURL = map.containsKey("swfUrl") ? (String)map.get("swfUrl") : "";
-		String tcUrl = map.containsKey("tcUrl") ? (String)map.get("tcUrl") : "";
-		Map<String, Object> connParams = getConnParams(params);
-		String uid = (String)connParams.get("uid");
-		if ("noclient".equals(uid)) {
-			return true;
-		}
-		String securityCode = (String)connParams.get(SECURITY_CODE_PARAM);
-		String parentSid = (String)map.get("parentSid");
-		if (parentSid == null) {
-			parentSid = (String)connParams.get("parentSid");
-		}
-		StringValue scn = StringValue.valueOf(conn.getScope().getName());
-		long roomId = scn.toLong(Long.MIN_VALUE);
-		Client rcm = new Client();
-		IApplication iapp = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
-		if (!Strings.isEmpty(securityCode)) {
-			//this is for external applications like ffmpeg [OPENMEETINGS-1574]
-			if (roomId < 0) {
-				log.warn("Trying to enter invalid scope using security code, client is rejected:: " + roomId);
-				return rejectClient();
-			}
-			String _uid = null;
-			for (org.apache.openmeetings.db.entity.basic.Client wcl : iapp.getOmRoomClients(roomId)) {
-				if (wcl.getSid().equals(securityCode)) {
-					_uid = wcl.getUid();
-					break;
-				}
-			}
-			if (_uid == null) {
-				log.warn("Client is not found by security id, client is rejected");
-				return rejectClient();
-			}
-			Client parent = sessionManager.getClientByPublicSID(_uid, null);
-			if (parent == null || !parent.getScope().equals(scn.toString())) {
-				log.warn("Security code is invalid, client is rejected");
-				return rejectClient();
-			}
-			rcm.setUsername(parent.getUsername());
-			rcm.setFirstname(parent.getFirstname());
-			rcm.setLastname(parent.getLastname());
-			rcm.setUserId(parent.getUserId());
-			rcm.setPublicSID(UUID.randomUUID().toString());
-			rcm.setSecurityCode(_uid);
-			Number width = (Number)connParams.get(WIDTH_PARAM);
-			Number height = (Number)connParams.get(HEIGHT_PARAM);
-			if (width != null && height != null) {
-				rcm.setVWidth(width.intValue());
-				rcm.setVHeight(height.intValue());
-			}
-		}
-		if (Strings.isEmpty(uid) && Strings.isEmpty(securityCode) && Strings.isEmpty(parentSid)) {
-			log.warn("No UIDs are provided, client is rejected");
-			return rejectClient();
-		}
-
-		if (map.containsKey("screenClient")) {
-			Client parent = sessionManager.getClientByPublicSID(parentSid, null);
-			if (parent == null) {
-				log.warn("Bad parent for screen-sharing client, client is rejected");
-				return rejectClient();
-			}
-			SessionVariablesUtil.setIsScreenClient(conn.getClient());
-			rcm.setUserId(parent.getUserId());
-			rcm.setScreenClient(true);
-			rcm.setPublicSID(UUID.randomUUID().toString());
-			rcm.setStreamPublishName(parentSid);
-		}
-		rcm.setStreamid(conn.getClient().getId());
-		rcm.setScope(scn.toString());
-		boolean notHibernate = !"hibernate".equals(scn.toString());
-		if (Long.MIN_VALUE != roomId) {
-			rcm.setRoomId(roomId);
-		} else if (notHibernate) {
-			log.warn("Bad room specified, client is rejected");
-			return rejectClient();
-		}
-		if (connParams.containsKey("mobileClient")) {
-			Sessiondata sd = sessiondataDao.check(parentSid);
-			if (sd.getUserId() == null && notHibernate) {
-				log.warn("Attempt of unauthorized room enter, client is rejected");
-				return rejectClient();
-			}
-			rcm.setMobile(true);
-			rcm.setUserId(sd.getUserId());
-			if (rcm.getUserId() != null) {
-				User u = userDao.get(rcm.getUserId());
-				if (u == null) {
-					log.error("Attempt of unauthorized room enter: USER not found, client is rejected");
-					return rejectClient();
-				}
-				rcm.setUsername(u.getLogin());
-				rcm.setFirstname(u.getFirstname());
-				rcm.setLastname(u.getLastname());
-				rcm.setEmail(u.getAddress() == null ? null : u.getAddress().getEmail());
-			}
-			rcm.setSecurityCode(sd.getSessionId());
-			rcm.setPublicSID(UUID.randomUUID().toString());
-		}
-		rcm.setUserport(conn.getRemotePort());
-		rcm.setUserip(conn.getRemoteAddress());
-		rcm.setSwfurl(swfURL);
-		rcm.setTcUrl(tcUrl);
-		if (!Strings.isEmpty(uid)) {
-			rcm.setPublicSID(uid);
-		}
-		rcm = sessionManager.add(iapp.updateClient(rcm, false), null);
-		if (rcm == null) {
-			log.warn("Failed to create Client on room connect");
-			return false;
-		}
-
-		SessionVariablesUtil.initClient(conn.getClient(), rcm.getPublicSID());
-		//TODO add similar code for other connections, merge with above block
-		if (map.containsKey("screenClient")) {
-			//TODO add check for room rights
-			User u = null;
-			Long userId = rcm.getUserId();
-			SessionVariablesUtil.setUserId(conn.getClient(), userId);
-			if (userId != null) {
-				long _uid = userId.longValue();
-				u = userDao.get(_uid < 0 ? -_uid : _uid);
-			}
-			if (u != null) {
-				rcm.setUsername(u.getLogin());
-				rcm.setFirstname(u.getFirstname());
-				rcm.setLastname(u.getLastname());
-			}
-			log.debug("publishName :: " + rcm.getStreamPublishName());
-			sessionManager.updateClientByStreamId(streamId, rcm, false, null);
-		}
-
-		// Log the User
-		conferenceLogDao.add(ConferenceLog.Type.clientConnect,
-				rcm.getUserId(), streamId, null, rcm.getUserip(),
-				rcm.getScope());
-		return true;
-	}
-
-	public Map<String, String> screenSharerAction(Map<String, Object> map) {
-		Map<String, String> returnMap = new HashMap<>();
-		try {
-			log.debug("-----------  screenSharerAction ENTER");
-			IConnection current = Red5.getConnectionLocal();
-
-			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-
-			if (client != null) {
-				boolean changed = false;
-				if (Boolean.parseBoolean("" + map.get("stopStreaming")) && client.isStartStreaming()) {
-					changed = true;
-					client.setStartStreaming(false);
-					//Send message to all users
-					sendMessageToCurrentScope("stopScreenSharingMessage", client, false);
-					WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
-
-					returnMap.put("result", "stopSharingOnly");
-				}
-				if (Boolean.parseBoolean("" + map.get("stopRecording")) && client.getIsRecording()) {
-					changed = true;
-					client.setStartRecording(false);
-					client.setIsRecording(false);
-
-					returnMap.put("result", "stopRecordingOnly");
-
-					recordingService.stopRecordAndSave(current.getScope(), client, null);
-				}
-				if (Boolean.parseBoolean("" + map.get("stopPublishing")) && client.isScreenPublishStarted()) {
-					changed = true;
-					client.setScreenPublishStarted(false);
-					returnMap.put("result", "stopPublishingOnly");
-
-					//Send message to all users
-					sendMessageToCurrentScope("stopPublishingMessage", client, false);
-				}
-
-				if (changed) {
-					sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
-
-					if (!client.isStartStreaming() && !client.isStartRecording() && !client.isStreamPublishStarted()) {
-						returnMap.put("result", "stopAll");
-					}
-				}
-			}
-			log.debug("-----------  screenSharerAction, return: " + returnMap);
-		} catch (Exception err) {
-			log.error("[screenSharerAction]", err);
-		}
-		return returnMap;
-	}
-
-	public List<Client> checkScreenSharing() {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			String streamid = current.getClient().getId();
-
-			log.debug("checkScreenSharing -2- " + streamid);
-
-			List<Client> screenSharerList = new LinkedList<>();
-
-			Client currentClient = sessionManager.getClientByStreamId(streamid, null);
-
-			for (Client rcl : sessionManager.getClientListByRoomAll(currentClient.getRoomId())) {
-				if (rcl.isStartStreaming()) {
-					screenSharerList.add(rcl);
-				}
-			}
-
-			return screenSharerList;
-
-		} catch (Exception err) {
-			log.error("[checkScreenSharing]", err);
-		}
-		return null;
-	}
-
-	/**
-	 *
-	 * @param map
-	 * @return returns key,value Map with multiple return values or null in case of exception
-	 *
-	 */
-	public Map<String, Object> setConnectionAsSharingClient(Map<String, Object> map) {
-		try {
-			log.debug("-----------  setConnectionAsSharingClient");
-			IConnection current = Red5.getConnectionLocal();
-
-			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-
-			if (client != null) {
-				boolean startRecording = Boolean.parseBoolean("" + map.get("startRecording"));
-				boolean startStreaming = Boolean.parseBoolean("" + map.get("startStreaming"));
-				boolean startPublishing = Boolean.parseBoolean("" + map.get("startPublishing")) && (0 == sessionManager.getPublishingCount(client.getRoomId()));
-
-				boolean alreadyStreaming = client.isStartStreaming();
-				if (startStreaming) {
-					client.setStartStreaming(true);
-				}
-				boolean alreadyRecording = client.isStartRecording();
-				if (startRecording) {
-					client.setStartRecording(true);
-				}
-				if (startPublishing) {
-					client.setStreamPublishStarted(true);
-				}
-
-				client.setVX(Double.valueOf("" + map.get("screenX")).intValue());
-				client.setVY(Double.valueOf("" + map.get("screenY")).intValue());
-				client.setVWidth(Double.valueOf("" + map.get("screenWidth")).intValue());
-				client.setVHeight(Double.valueOf("" + map.get("screenHeight")).intValue());
-				client.setStreamPublishName("" + map.get("publishName"));
-				sessionManager.updateClientByStreamId(current.getClient().getId(), client, false, null);
-
-				Map<String, Object> returnMap = new HashMap<>();
-				returnMap.put("alreadyPublished", false);
-
-				// if is already started screen sharing, then there is no need
-				// to start it again
-				if (client.isScreenPublishStarted()) {
-					returnMap.put("alreadyPublished", true);
-				}
-
-				log.debug("screen x,y,width,height {},{},{},{}", client.getVX(), client.getVY(), client.getVWidth(), client.getVHeight());
-
-				if (startStreaming) {
-					if (!alreadyStreaming) {
-						returnMap.put("modus", "startStreaming");
-
-						log.debug("start streamPublishStart Is Screen Sharing ");
-
-						//Send message to all users
-						sendMessageToCurrentScope("newScreenSharing", client, false);
-						WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStarted, client.getStreamPublishName()));
-					} else {
-						log.warn("Streaming is already started for the client id=" + client.getId() + ". Second request is ignored.");
-					}
-				}
-				if (startRecording) {
-					if (!alreadyRecording) {
-						returnMap.put("modus", "startRecording");
-
-						String recordingName = "Recording " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
-
-						recordingService.recordMeetingStream(current, client, recordingName, "", false);
-					} else {
-						log.warn("Recording is already started for the client id=" + client.getId() + ". Second request is ignored.");
-					}
-				}
-				if (startPublishing) {
-					sendMessageToCurrentScope("startedPublishing", new Object[]{client, "rtmp://" + map.get("publishingHost") + ":1935/"
-							+ map.get("publishingApp") + "/" + map.get("publishingId")}, false, true);
-					returnMap.put("modus", "startPublishing");
-				}
-				return returnMap;
-			} else {
-				log.error("[setConnectionAsSharingClient] Could not find Screen Sharing Client " + current.getClient().getId());
-			}
-		} catch (Exception err) {
-			log.error("[setConnectionAsSharingClient]", err);
-		}
-		return null;
-	}
-
-	public List<Long> listRoomBroadcast() {
-		Set<Long> broadcastList = new HashSet<>();
-		IConnection current = Red5.getConnectionLocal();
-		String streamid = current.getClient().getId();
-		for (IConnection conn : current.getScope().getClientConnections()) {
-			if (conn != null) {
-				Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-				if (rcl == null) {
-					// continue;
-				} else if (rcl.isScreenClient()) {
-					// continue;
-				} else {
-					if (!streamid.equals(rcl.getStreamid())) {
-						// It is not needed to send back
-						// that event to the actuall
-						// Moderator
-						// as it will be already triggered
-						// in the result of this Function
-						// in the Client
-						Long id = Long.valueOf(rcl.getBroadCastID());
-						if (!broadcastList.contains(id)) {
-							broadcastList.add(id);
-						}
-					}
-				}
-			}
-		}
-		return new ArrayList<>(broadcastList);
-	}
-
-	/**
-	 * this function is invoked directly after initial connecting
-	 *
-	 * @return publicSID of current client
-	 */
-	public String getPublicSID() {
-		log.debug("-----------  getPublicSID");
-		IConnection current = Red5.getConnectionLocal();
-		Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-		sessionManager.updateClientByStreamId(current.getClient().getId(), currentClient, false, null);
-		return currentClient.getPublicSID();
-	}
-
-	/**
-	 * this function is invoked after a reconnect
-	 *
-	 * @param newPublicSID
-	 */
-	public boolean overwritePublicSID(String newPublicSID) {
-		try {
-			log.debug("-----------  overwritePublicSID");
-			IConnection current = Red5.getConnectionLocal();
-			IClient c = current.getClient();
-			Client currentClient = sessionManager.getClientByStreamId(c.getId(), null);
-			if (currentClient == null) {
-				return false;
-			}
-			SessionVariablesUtil.initClient(c, newPublicSID);
-			currentClient.setPublicSID(newPublicSID);
-			sessionManager.updateClientByStreamId(c.getId(), currentClient, false, null);
-			return true;
-		} catch (Exception err) {
-			log.error("[overwritePublicSID]", err);
-		}
-		return false;
-	}
-
-	/**
-	 * Logic must be before roomDisconnect cause otherwise you cannot throw a
-	 * message to each one
-	 *
-	 */
-	@Override
-	public void roomLeave(IClient client, IScope room) {
-		try {
-			log.debug("[roomLeave] {} {} {} {}", client.getId(), room.getClients().size(), room.getContextPath(), room.getName());
-
-			Client rcl = sessionManager.getClientByStreamId(client.getId(), null);
-
-			// The Room Client can be null if the Client left the room by using
-			// logicalRoomLeave
-			if (rcl != null) {
-				log.debug("currentClient IS NOT NULL");
-				roomLeaveByScope(rcl, room);
-			}
-		} catch (Exception err) {
-			log.error("[roomLeave]", err);
-		}
-	}
-
-	public void roomLeaveByScope(String uid, Long roomId) {
-		Client rcl = sessionManager.getClientByPublicSID(uid, null);
-		IScope scope = getRoomScope("" + roomId);
-		log.debug("[roomLeaveByScope] {} {} {} {}", uid, roomId, rcl, scope);
-		if (rcl != null && scope != null) {
-			roomLeaveByScope(rcl, scope);
-		}
-	}
-
-	/**
-	 * Removes the Client from the List, stops recording, adds the Room-Leave
-	 * event to running recordings, clear Polls and removes Client from any list
-	 *
-	 * This function is kind of private/protected as the client won't be able
-	 * to call it with proper values.
-	 *
-	 * @param client
-	 * @param scope
-	 */
-	public void roomLeaveByScope(Client client, IScope scope) {
-		try {
-			log.debug("[roomLeaveByScope] currentClient " + client);
-			if (client.isScreenClient() && client.isStartStreaming()) {
-				//TODO check others/find better way
-				WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
-			}
-
-			log.debug("removing Username " + client.getUsername() + " "
-					+ client.getConnectedSince() + " streamid: "
-					+ client.getStreamid());
-
-			// stop and save any recordings
-			if (client.getIsRecording()) {
-				log.debug("*** roomLeave Current Client is Recording - stop that");
-				if (client.getInterviewPodId() != null) {
-					//interview, TODO need better check
-					_stopInterviewRecording(client, scope);
-				} else {
-					recordingService.stopRecordAndSave(scope, client, null);
-
-					// set to true and overwrite the default one cause otherwise no
-					// notification is send
-					client.setIsRecording(true);
-				}
-			}
-			recordingService.stopRecordingShowForClient(scope, client);
-
-			// Notify all clients of the same currentScope (room) with domain
-			// and room except the current disconnected cause it could throw an exception
-			log.debug("currentScope " + scope);
-
-			new MessageSender(scope, "roomDisconnect", client, this) {
-				@Override
-				public boolean filter(IConnection conn) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-					if (rcl == null) {
-						return true;
-					}
-					boolean isScreen = rcl.isScreenClient();
-					if (isScreen && client.getPublicSID().equals(rcl.getStreamPublishName())) {
-						//going to terminate screen sharing started by this client
-						((IServiceCapableConnection) conn).invoke("stopStream", new Object[] { }, callback);
-					}
-					return isScreen;
-				}
-			}.start();
-
-			if (client.isMobile()) {
-				IApplication app = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
-				app.exit(client.getPublicSID());
-			}
-			sessionManager.removeClient(client.getStreamid(), null);
-		} catch (Exception err) {
-			log.error("[roomLeaveByScope]", err);
-		}
-	}
-
-	/**
-	 * This method handles the Event after a stream has been added all connected
-	 * Clients in the same room will get a notification
-	 *
-	 */
-	/* (non-Javadoc)
-	 * @see org.red5.server.adapter.MultiThreadedApplicationAdapter#streamPublishStart(org.red5.server.api.stream.IBroadcastStream)
-	 */
-	@Override
-	public void streamPublishStart(IBroadcastStream stream) {
-		try {
-			log.debug("-----------  streamPublishStart");
-			IConnection current = Red5.getConnectionLocal();
-			final String streamid = current.getClient().getId();
-			final Client c = sessionManager.getClientByStreamId(streamid, null);
-
-			//We make a second object the has the reference to the object
-			//that we will use to send to all participents
-			Client clientObjectSendToSync = c;
-
-			// Notify all the clients that the stream had been started
-			log.debug("start streamPublishStart broadcast start: " + stream.getPublishedName() + " CONN " + current);
-
-			// In case its a screen sharing we start a new Video for that
-			if (c.isScreenClient()) {
-				c.setScreenPublishStarted(true);
-				sessionManager.updateClientByStreamId(streamid, c, false, null);
-			}
-			if (!c.isMobile() && !Strings.isEmpty(c.getSecurityCode())) {
-				c.setBroadCastID(Long.parseLong(stream.getPublishedName()));
-				c.setAvsettings("av");
-				c.setIsBroadcasting(true);
-				if (c.getVWidth() == 0 || c.getVHeight() == 0) {
-					c.setVWidth(320);
-					c.setVHeight(240);
-				}
-				sessionManager.updateClientByStreamId(streamid, c, false, null);
-			}
-
-			log.debug("newStream SEND: " + c);
-
-			// Notify all users of the same Scope
-			// We need to iterate through the streams to catch if anybody is recording
-			new MessageSender(current, "newStream", clientObjectSendToSync, this) {
-				@Override
-				public boolean filter(IConnection conn) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-
-					if (rcl == null) {
-						log.debug("RCL IS NULL newStream SEND");
-						return true;
-					}
-
-					log.debug("check send to "+rcl);
-
-					if (Strings.isEmpty(rcl.getPublicSID())) {
-						log.debug("publicSID IS NULL newStream SEND");
-						return true;
-					}
-					if (rcl.getIsRecording()) {
-						log.debug("RCL getIsRecording newStream SEND");
-						recordingService.addRecordingByStreamId(current, c, rcl.getRecordingId());
-					}
-					if (rcl.isScreenClient()) {
-						log.debug("RCL getIsScreenClient newStream SEND");
-						return true;
-					}
-
-					if (rcl.getPublicSID().equals(c.getPublicSID())) {
-						log.debug("RCL publicSID is equal newStream SEND");
-						return true;
-					}
-					log.debug("RCL SEND is equal newStream SEND "+rcl.getPublicSID()+" || "+rcl.getUserport());
-					return false;
-				}
-			}.start();
-		} catch (Exception err) {
-			log.error("[streamPublishStart]", err);
-		}
-	}
-
-	public IBroadcastScope getBroadcastScope(IScope scope, String name) {
-		IBasicScope basicScope = scope.getBasicScope(ScopeType.BROADCAST, name);
-		if (!(basicScope instanceof IBroadcastScope)) {
-			return null;
-		} else {
-			return (IBroadcastScope) basicScope;
-		}
-	}
-
-	/**
-	 * This method handles the Event after a stream has been removed all
-	 * connected Clients in the same room will get a notification
-	 *
-	 */
-	/* (non-Javadoc)
-	 * @see org.red5.server.adapter.MultiThreadedApplicationAdapter#streamBroadcastClose(org.red5.server.api.stream.IBroadcastStream)
-	 */
-	@Override
-	public void streamBroadcastClose(IBroadcastStream stream) {
-		// Notify all the clients that the stream had been closed
-		log.debug("start streamBroadcastClose broadcast close: " + stream.getPublishedName());
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			String streamId = current.getClient().getId();
-			Client rcl = sessionManager.getClientByStreamId(streamId, null);
-
-			if (rcl == null) {
-
-				// In case the client has already left(kicked) this message
-				// might be thrown later then the RoomLeave
-				// event and the currentClient is already gone
-				// The second Use-Case where the currentClient is maybe null is
-				// if we remove the client because its a Zombie/Ghost
-
-				return;
-
-			}
-			// Notify all the clients that the stream had been started
-			log.debug("streamBroadcastClose : " + rcl + " " + rcl.getStreamid());
-			// this close stream event, stop the recording of this stream
-			if (rcl.getIsRecording()) {
-				log.debug("***  +++++++ ######## sendClientBroadcastNotifications Any Client is Recording - stop that");
-				recordingService.stopRecordingShowForClient(current.getScope(), rcl);
-			}
-			if (stream.getPublishedName().equals("" + rcl.getBroadCastID())) {
-				rcl.setBroadCastID(-1);
-				rcl.setIsBroadcasting(false);
-				rcl.setAvsettings("n");
-			}
-			sessionManager.updateClientByStreamId(streamId, rcl, false, null);
-			// Notify all clients of the same scope (room)
-			sendMessageToCurrentScope("closeStream", rcl, rcl.isMobile());
-		} catch (Exception e) {
-			log.error("[streamBroadcastClose]", e);
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	public void setNewCursorPosition(Object item) {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-
-			@SuppressWarnings("rawtypes")
-			Map cursor = (Map) item;
-			cursor.put("streamPublishName", c.getStreamPublishName());
-
-			sendMessageToCurrentScope("newRed5ScreenCursor", cursor, true, false);
-		} catch (Exception err) {
-			log.error("[setNewCursorPosition]", err);
-		}
-	}
-
-	public long removeModerator(String publicSID) {
-		try {
-			log.debug("-----------  removeModerator: " + publicSID);
-
-			Client currentClient = sessionManager.getClientByPublicSID(publicSID, null);
-
-			if (currentClient == null) {
-				return -1L;
-			}
-			Long roomId = currentClient.getRoomId();
-
-			currentClient.setIsMod(false);
-			// Put the mod-flag to true for this client
-			sessionManager.updateClientByStreamId(currentClient.getStreamid(), currentClient, false, null);
-
-			List<Client> currentMods = sessionManager.getCurrentModeratorByRoom(roomId);
-
-			sendMessageToCurrentScope("setNewModeratorByList", currentMods, true);
-		} catch (Exception err) {
-			log.error("[removeModerator]", err);
-		}
-		return -1L;
-	}
-
-	public long switchMicMuted(String publicSID, boolean mute) {
-		try {
-			log.debug("-----------  switchMicMuted: " + publicSID);
-
-			Client currentClient = sessionManager.getClientByPublicSID(publicSID, null);
-			if (currentClient == null) {
-				return -1L;
-			}
-
-			currentClient.setMicMuted(mute);
-			sessionManager.updateClientByStreamId(currentClient.getStreamid(), currentClient, false, null);
-
-			Map<Integer, Object> newMessage = new HashMap<>();
-			newMessage.put(0, "updateMuteStatus");
-			newMessage.put(1, currentClient);
-			sendMessageWithClient(newMessage);
-		} catch (Exception err) {
-			log.error("[switchMicMuted]", err);
-		}
-		return 0L;
-	}
-
-	public boolean getMicMutedByPublicSID(String publicSID) {
-		try {
-			Client currentClient = sessionManager.getClientByPublicSID(publicSID, null);
-			if (currentClient == null) {
-				return true;
-			}
-
-			//Put the mod-flag to true for this client
-			return currentClient.getMicMuted();
-		} catch (Exception err) {
-			log.error("[getMicMutedByPublicSID]",err);
-		}
-		return true;
-	}
-
-	public static long nextBroadCastId() {
-		return broadCastCounter.getAndIncrement();
-	}
-
-	/**
-	 * This method is used to set/update broadCastID of current client
-	 *
-	 * @param updateBroadcastId boolean flag
-	 *
-	 * @return BroadcastId in case of no errors, -1 otherwise
-	 */
-	public long setUserAVSettings(boolean updateBroadcastId) {
-		try {
-			String streamid = Red5.getConnectionLocal().getClient().getId();
-			log.debug("-----------  setUserAVSettings {}", streamid);
-			Client rcl = sessionManager.getClientByStreamId(streamid, null);
-			if (rcl == null) {
-				log.warn("Failed to find appropriate clients");
-				return -1;
-			}
-			if (updateBroadcastId) {
-				rcl.setBroadCastID(nextBroadCastId());
-				sessionManager.updateAVClientByStreamId(streamid, rcl, null);
-			}
-			return rcl.getBroadCastID();
-		} catch (Exception err) {
-			log.error("[setUserAVSettings]", err);
-		}
-		return -1;
-	}
-
-	/*
-	 * checks if the user is allowed to apply for Moderation
-	 */
-	public boolean checkRoomValues(Long roomId) {
-		try {
-
-			// appointed meeting or moderated Room?
-			Room room = roomDao.get(roomId);
-
-			// not really - default logic
-			if (!room.isAppointment() && room.isModerated()) {
-				// if this is a Moderated Room then the Room can be only
-				// locked off by the Moderator Bit
-				List<Client> clientModeratorListRoom = sessionManager.getCurrentModeratorByRoom(roomId);
-
-				// If there is no Moderator yet and we are asking for it
-				// then deny it
-				// cause at this moment, the user should wait untill a
-				// Moderator enters the Room
-				return clientModeratorListRoom.size() != 0;
-			} else {
-				// FIXME: TODO: For Rooms that are created as Appointment we
-				// have to check that too
-				// but I don't know yet the Logic behind it - swagner 19.06.2009
-				return true;
-
-			}
-		} catch (Exception err) {
-			log.error("[checkRoomValues]", err);
-		}
-		return false;
-	}
-
-	/**
-	 * This function is called once a User enters a Room
-	 *
-	 * It contains several different mechanism depending on what roomtype and
-	 * what options are available for the room to find out if the current user
-	 * will be a moderator of that room or not<br/>
-	 * <br/>
-	 * Some rules:<br/>
-	 * <ul>
-	 * <li>If it is a room that was created through the calendar, the user that
-	 * organized the room will be moderator, the param Boolean becomeModerator
-	 * will be ignored then</li>
-	 * <li>In regular rooms you can use the param Boolean becomeModerator to set
-	 * any user to become a moderator of the room</li>
-	 * </ul>
-	 * <br/>
-	 * If a new moderator is detected a Push Call to all current users of the
-	 * room is invoked "setNewModeratorByList" to notify them of the new
-	 * moderator<br/>
-	 * <br/>
-	 * At the end of the mechanism a push call with the new client-object
-	 * and all the informations about the new user is send to every user of the
-	 * current conference room<br/>
-	 * <br/>
-	 *
-	 * @param roomId - id of the room
-	 * @param becomeModerator - is user will become moderator
-	 * @param isSuperModerator - is user super moderator
-	 * @param groupId - group id of the user
-	 * @param colorObj - some color
-	 * @return RoomStatus object
-	 */
-	public RoomStatus setRoomValues(Long roomId, boolean becomeModerator, boolean isSuperModerator, String colorObj) {
-		try {
-			log.debug("-----------  setRoomValues");
-			IConnection current = Red5.getConnectionLocal();
-			String streamid = current.getClient().getId();
-			Client client = sessionManager.getClientByStreamId(streamid, null);
-			client.setRoomId(roomId);
-			client.setRoomEnter(new Date());
-
-			client.setUsercolor(colorObj);
-
-			Long userId = client.getUserId();
-			User u = userId == null ? null : userDao.get(userId > 0 ? userId : -userId);
-			// Inject externalUserId if nothing is set yet
-			if (client.getExternalUserId() == null && u != null) {
-				client.setExternalUserId(u.getExternalId());
-				client.setExternalUserType(u.getExternalType());
-			}
-
-			Room r = roomDao.get(roomId);
-			if (!r.isHidden(RoomElement.MicrophoneStatus)) {
-				client.setCanGiveAudio(true);
-			}
-			sessionManager.updateClientByStreamId(streamid, client, true, null); // first save to get valid room count
-
-			// Check for Moderation LogicalRoom ENTER
-			List<Client> roomClients = sessionManager.getClientListByRoom(roomId);
-
-			// Return Object
-			RoomStatus roomStatus = new RoomStatus();
-			// appointed meeting or moderated Room? => Check Max Users first
-			if (isSuperModerator) {
-				// This can be set without checking for Moderation Flag
-				client.setIsSuperModerator(isSuperModerator);
-				client.setIsMod(isSuperModerator);
-			} else {
-				Set<Room.Right> rr = AuthLevelUtil.getRoomRight(u, r, r.isAppointment() ? appointmentDao.getByRoom(r.getId()) : null, roomClients.size());
-				client.setIsSuperModerator(rr.contains(Room.Right.superModerator));
-				client.setIsMod(becomeModerator || rr.contains(Room.Right.moderator));
-			}
-			if (client.getIsMod()) {
-				// Update the Client List
-				sessionManager.updateClientByStreamId(streamid, client, false, null);
-
-				List<Client> modRoomList = sessionManager.getCurrentModeratorByRoom(client.getRoomId());
-
-				//Sync message to everybody
-				sendMessageToCurrentScope("setNewModeratorByList", modRoomList, false);
-			}
-
-			//Sync message to everybody
-			sendMessageToCurrentScope("addNewUser", client, false);
-
-			//Status object for Shared Browsing
-			BrowserStatus browserStatus = (BrowserStatus)current.getScope().getAttribute("browserStatus");
-
-			if (browserStatus == null) {
-				browserStatus = new BrowserStatus();
-			}
-
-			// RoomStatus roomStatus = new RoomStatus();
-
-			// FIXME: Rework Client Object to DTOs
-			roomStatus.setClientList(roomClients);
-			roomStatus.setBrowserStatus(browserStatus);
-
-			return roomStatus;
-		} catch (Exception err) {
-			log.error("[setRoomValues]", err);
-		}
-		return null;
-	}
-
-	/**
-	 * this is set initial directly after login/loading language
-	 *
-	 * @param SID - id of the session
-	 * @param userId - id of the user being set
-	 * @param username - username of the user
-	 * @param firstname - firstname of the user
-	 * @param lastname - lastname of the user
-	 * @return RoomClient in case of everything is OK, null otherwise
-	 */
-	public Client setUsernameAndSession(String SID, Long userId, String username, String firstname, String lastname) {
-		try {
-			log.debug("-----------  setUsernameAndSession");
-			IConnection current = Red5.getConnectionLocal();
-			String streamid = current.getClient().getId();
-			Client currentClient = sessionManager.getClientByStreamId(streamid, null);
-
-			currentClient.setUsername(username);
-			currentClient.setUserId(userId);
-			SessionVariablesUtil.setUserId(current.getClient(), userId);
-			currentClient.setUserObject(userId, username, firstname, lastname);
-
-			// Update Session Data
-			log.debug("UDPATE SESSION " + SID + ", " + userId);
-			sessiondataDao.updateUserWithoutSession(SID, userId);
-
-			User user = userDao.get(userId);
-
-			if (user != null) {
-				currentClient.setExternalUserId(user.getExternalId());
-				currentClient.setExternalUserType(user.getExternalType());
-			}
-
-			// only fill this value from User-Record
-			// cause invited users have non
-			// you cannot set the firstname,lastname from the UserRecord
-			User us = userDao.get(userId);
-			if (us != null && us.getPictureuri() != null) {
-				// set Picture-URI
-				currentClient.setPicture_uri(us.getPictureuri());
-			}
-			sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-			return currentClient;
-		} catch (Exception err) {
-			log.error("[setUsername]", err);
-		}
-		return null;
-	}
-
-	/**
-	 * used by the Screen-Sharing Servlet to trigger events
-	 *
-	 * @param roomId
-	 * @param message
-	 * @return the list of room clients
-	 */
-	public Map<String, Client> sendMessageByRoomAndDomain(Long roomId, Object message) {
-		Map<String, Client> roomClientList = new HashMap<>();
-		try {
-
-			log.debug("sendMessageByRoomAndDomain " + roomId);
-
-			IScope scope = getRoomScope(roomId.toString());
-
-			new MessageSender(scope, "newMessageByRoomAndDomain", message, this) {
-				@Override
-				public boolean filter(IConnection conn) {
-					IClient client = conn.getClient();
-					return SessionVariablesUtil.isScreenClient(client);
-				}
-			}.start();
-		} catch (Exception err) {
-			log.error("[getClientListBYRoomAndDomain]", err);
-		}
-		return roomClientList;
-	}
-
-	public List<Client> getCurrentModeratorList() {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-			Long roomId = client.getRoomId();
-			Room r = roomDao.get(roomId);
-			if (r != null) {
-				return sessionManager.getCurrentModeratorByRoom(roomId);
-			}
-		} catch (Exception err) {
-			log.error("[getCurrentModerator]", err);
-		}
-		return null;
-	}
-
-	public int sendMessage(Object newMessage) {
-		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
-		return 1;
-	}
-
-	public int sendMessageAll(Object newMessage) {
-		sendMessageToCurrentScope("sendVarsToMessage", newMessage, true);
-		return 1;
-	}
-
-	/**
-	 * send status for shared browsing to all members except self
-	 * @param newMessage
-	 * @return 1
-	 */
-	@SuppressWarnings({ "rawtypes" })
-	public int sendBrowserMessageToMembers(Object newMessage) {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-
-			List newMessageList = (List) newMessage;
-
-			String action = newMessageList.get(0).toString();
-
-			BrowserStatus browserStatus = (BrowserStatus) current.getScope().getAttribute("browserStatus");
-
-			if (browserStatus == null) {
-				browserStatus = new BrowserStatus();
-			}
-
-			if (action.equals("initBrowser") || action.equals("newBrowserURL")) {
-				browserStatus.setBrowserInited(true);
-				browserStatus.setCurrentURL(newMessageList.get(1).toString());
-			} else if (action.equals("closeBrowserURL")) {
-				browserStatus.setBrowserInited(false);
-			}
-
-			current.getScope().setAttribute("browserStatus", browserStatus);
-
-			sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
-
-		} catch (Exception err) {
-			log.error("[sendMessage]", err);
-		}
-		return 1;
-	}
-
-	/**
-	 * wrapper method
-	 * @param newMessage
-	 */
-	public void sendMessageToMembers(List<?> newMessage) {
-		//Sync to all users of current scope
-		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
-	}
-
-	/**
-	 * General sync mechanism for all messages that are send from within the
-	 * scope of the current client, but:
-	 * <ul>
-	 * <li>optionally do not send to self (see param: sendSelf)</li>
-	 * <li>do not send to clients that are screen sharing clients</li>
-	 * <li>do not send to clients that are audio/video clients (or potentially ones)</li>
-	 * <li>do not send to connections where no RoomClient is registered</li>
-	 * </ul>
-	 *
-	 * @param remoteMethodName The method to be called
-	 * @param newMessage parameters
-	 * @param sendSelf send to the current client as well
-	 */
-	public void sendMessageToCurrentScope(String remoteMethodName, Object newMessage, boolean sendSelf) {
-		sendMessageToCurrentScope(remoteMethodName, newMessage, sendSelf, false);
-	}
-
-	public void sendMessageToCurrentScope(String scopeName, String remoteMethodName, Object newMessage, boolean sendSelf) {
-		sendMessageToCurrentScope(scopeName, remoteMethodName, newMessage, sendSelf, false);
-	}
-
-	public void sendToScope(final Long roomId, String method, Object obj) {
-		new MessageSender(getRoomScope("" + roomId), method, obj, this) {
-			@Override
-			public boolean filter(IConnection conn) {
-				Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-				return rcl == null || rcl.isScreenClient()
-						|| rcl.getRoomId() == null || !rcl.getRoomId().equals(roomId) || userDao.get(rcl.getUserId()) == null;
-			}
-		}.start();
-	}
-
-	/**
-	 * Only temporary for load test, with return argument for the client to have a result
-	 *
-	 * @param remoteMethodName
-	 * @param newMessage
-	 * @param sendSelf
-	 * @return true
-	 */
-	@Deprecated
-	public boolean loadTestSyncMessage(String remoteMethodName, Object newMessage, boolean sendSelf) {
-		sendMessageToCurrentScope(remoteMethodName, newMessage, sendSelf, false);
-		return true;
-	}
-
-	/**
-	 * General sync mechanism for all messages that are send from within the
-	 * scope of the current client, but:
-	 * <ul>
-	 * <li>optionally do not send to self (see param: sendSelf)</li>
-	 * <li>send to clients that are screen sharing clients based on parameter</li>
-	 * <li>do not send to clients that are audio/video clients (or potentially ones)</li>
-	 * <li>do not send to connections where no RoomClient is registered</li>
-	 * </ul>
-	 *
-	 * @param method The method to be called
-	 * @param msg parameters
-	 * @param sendSelf send to the current client as well
-	 * @param sendScreen send to the current client as well
-	 */
-	public void sendMessageToCurrentScope(final String method, final Object msg, final boolean sendSelf, final boolean sendScreen) {
-		IConnection conn = Red5.getConnectionLocal();
-		if (conn == null) {
-			log.warn("[sendMessageToCurrentScope] -> 'Unable to send message using NULL connection' {}, {}", method, msg);
-			return;
-		}
-		sendMessageToCurrentScope(conn.getScope().getName(), method, msg, sendSelf, sendScreen);
-	}
-
-	public void sendMessageToCurrentScope(final String scopeName, final String remoteMethodName, final Object newMessage, final boolean sendSelf, final boolean sendScreen) {
-		new MessageSender(getRoomScope(scopeName), remoteMethodName, newMessage, this) {
-			@Override
-			public boolean filter(IConnection conn) {
-				IClient client = conn.getClient();
-				return (!sendScreen && SessionVariablesUtil.isScreenClient(client))
-						|| (!sendSelf && current != null && client.getId().equals(current.getClient().getId()));
-			}
-		}.start();
-	}
-
-	public static abstract class MessageSender extends Thread {
-		final IScope scope;
-		final IConnection current;
-		final String method;
-		final Object msg;
-		final IPendingServiceCallback callback;
-
-		public MessageSender(final String remoteMethodName, final Object newMessage, IPendingServiceCallback callback) {
-			this((IScope)null, remoteMethodName, newMessage, callback);
-		}
-
-		public MessageSender(IScope _scope, String method, Object msg, IPendingServiceCallback callback) {
-			this(Red5.getConnectionLocal(), _scope, method, msg, callback);
-		}
-
-		public MessageSender(IConnection current, String method, Object msg, IPendingServiceCallback callback) {
-			this(current, null, method, msg, callback);
-		}
-
-		public MessageSender(IConnection current, IScope _scope, String method, Object msg, IPendingServiceCallback callback) {
-			this.current = current;
-			scope = _scope == null && current != null ? current.getScope() : _scope;
-			this.method = method;
-			this.msg = msg;
-			this.callback = callback;
-		}
-
-		public abstract boolean filter(IConnection conn);
-
-		@Override
-		public void run() {
-			try {
-				if (scope == null) {
-					log.debug("[MessageSender] -> 'Unable to send message to NULL scope' {}, {}", method, msg);
-				} else {
-					if (log.isTraceEnabled()) {
-						log.trace("[MessageSender] -> 'sending message' {}, {}", method, msg);
-					}
-					// Send to all Clients of that Scope(Room)
-					int count = 0;
-					for (IConnection conn : scope.getClientConnections()) {
-						if (conn != null && conn instanceof IServiceCapableConnection) {
-							if (filter(conn)) {
-								continue;
-							}
-							((IServiceCapableConnection) conn).invoke(method, new Object[] { msg }, callback);
-							count++;
-						}
-					}
-					if (log.isTraceEnabled()) {
-						log.trace("[MessageSender] -> 'sending message to {} clients, DONE' {}", count, method);
-					}
-				}
-			} catch (Exception err) {
-				log.error(String.format("[MessageSender -> %s, %s]", method, msg), err);
-			}
-		}
-	}
-
-	/**
-	 * wrapper method
-	 * @param newMessage
-	 * @return 1 in case of success, -1 otherwise
-	 */
-	public int sendMessageWithClient(Object newMessage) {
-		try {
-			sendMessageWithClientWithSyncObject(newMessage, true);
-
-		} catch (Exception err) {
-			log.error("[sendMessageWithClient] ", err);
-			return -1;
-		}
-		return 1;
-	}
-
-	/**
-	 * wrapper method
-	 * @param newMessage
-	 * @param sync
-	 * @return 1 in case of success, -1 otherwise
-	 */
-	public int sendMessageWithClientWithSyncObject(Object newMessage, boolean sync) {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-
-			Map<String, Object> hsm = new HashMap<>();
-			hsm.put("client", currentClient);
-			hsm.put("message", newMessage);
-
-			//Sync to all users of current scope
-			sendMessageToCurrentScope("sendVarsToMessageWithClient", hsm, sync);
-
-		} catch (Exception err) {
-			log.error("[sendMessageWithClient] ", err);
-			return -1;
-		}
-		return 1;
-	}
-
-	/**
-	 * Function is used to send the kick Trigger at the moment,
-	 * it sends a general message to a specific clientId
-	 *
-	 * @param newMessage
-	 * @param clientId
-	 * @return 1 in case of success, -1 otherwise
-	 */
-	public int sendMessageById(Object newMessage, String clientId, IScope scope) {
-		try {
-			log.debug("### sendMessageById ###" + clientId);
-
-			Map<String, Object> hsm = new HashMap<>();
-			hsm.put("message", newMessage);
-
-			// broadcast Message to specific user with id inside the same Scope
-			for (IConnection conn : scope.getClientConnections()) {
-				if (conn != null) {
-					if (conn instanceof IServiceCapableConnection) {
-						if (conn.getClient().getId().equals(clientId)) {
-							((IServiceCapableConnection) conn).invoke("sendVarsToMessageWithClient", new Object[] { hsm }, this);
-						}
-					}
-				}
-			}
-		} catch (Exception err) {
-			log.error("[sendMessageWithClient] ", err);
-			return -1;
-		}
-		return 1;
-	}
-
-	/**
-	 * Sends a message to a user in the same room by its clientId
-	 *
-	 * @param newMessage
-	 * @param clientId
-	 * @return 1 in case of no exceptions, -1 otherwise
-	 */
-	public int sendMessageWithClientById(Object newMessage, String clientId) {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-
-			Map<String, Object> hsm = new HashMap<>();
-			hsm.put("client", currentClient);
-			hsm.put("message", newMessage);
-
-			// broadcast Message to specific user with id inside the same Scope
-			for (IConnection conn : current.getScope().getClientConnections()) {
-				if (conn.getClient().getId().equals(clientId)) {
-					((IServiceCapableConnection) conn).invoke("sendVarsToMessageWithClient", new Object[] { hsm }, this);
-				}
-			}
-		} catch (Exception err) {
-			log.error("[sendMessageWithClient] ", err);
-			return -1;
-		}
-		return 1;
-	}
-
-	public void sendMessageWithClientByPublicSID(Object message, String publicSID) {
-		try {
-			if (publicSID == null) {
-				log.warn("'null' publicSID was passed to sendMessageWithClientByPublicSID");
-				return;
-			}
-
-			// Get Room Id to send it to the correct Scope
-			Client currentClient = sessionManager.getClientByPublicSID(publicSID, null);
-
-			if (currentClient == null) {
-				throw new Exception("Could not Find RoomClient on List publicSID: " + publicSID);
-			}
-			IScope scope = getRoomScope("" + currentClient.getRoomId());
-
-			// log.debug("scopeHibernate "+scopeHibernate);
-
-			if (scope != null) {
-				// Notify the clients of the same scope (room) with userId
-
-				for (IConnection conn : scope.getClientConnections()) {
-					IClient client = conn.getClient();
-					if (SessionVariablesUtil.isScreenClient(client)) {
-						// screen sharing clients do not receive events
-						continue;
-					}
-
-					if (publicSID.equals(SessionVariablesUtil.getPublicSID(client))) {
-						((IServiceCapableConnection) conn).invoke("newMessageByRoomAndDomain", new Object[] { message }, this);
-					}
-				}
-			} else {
-				// Scope not yet started
-			}
-		} catch (Exception err) {
-			log.error("[sendMessageWithClientByPublicSID] ", err);
-		}
-	}
-
-	/**
-	 * @deprecated this method should be reworked to use a single SQL query in
-	 *             the cache to get any client in the current room that is
-	 *             recording instead of iterating through connections!
-	 * @return true in case there is recording session, false otherwise, null if any exception happend
-	 */
-	@Deprecated
-	public boolean getInterviewRecordingStatus() {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-
-			for (IConnection conn : current.getScope().getClientConnections()) {
-				if (conn != null) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-
-					if (rcl.getIsRecording()) {
-						return true;
-					}
-				}
-			}
-		} catch (Exception err) {
-			log.error("[getInterviewRecordingStatus]", err);
-		}
-		return false;
-	}
-
-	/**
-	 * @deprecated @see {@link ScopeApplicationAdapter#getInterviewRecordingStatus()}
-	 * @return - false if there were existing recording, true if recording was started successfully, null if any exception happens
-	 */
-	@Deprecated
-	public boolean startInterviewRecording() {
-		try {
-			log.debug("-----------  startInterviewRecording");
-			IConnection current = Red5.getConnectionLocal();
-
-			for (IConnection conn : current.getScope().getClientConnections()) {
-				if (conn != null) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-
-					if (rcl != null && rcl.getIsRecording()) {
-						return false;
-					}
-				}
-			}
-			Client current_rcl = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-
-			// Also set the Recording Flag to Record all Participants that enter
-			// later
-			current_rcl.setIsRecording(true);
-			sessionManager.updateClientByStreamId(current.getClient().getId(), current_rcl, false, null);
-
-			Map<String, String> interviewStatus = new HashMap<>();
-			interviewStatus.put("action", "start");
-
-			for (IConnection conn : current.getScope().getClientConnections()) {
-				if (conn != null) {
-					IClient client = conn.getClient();
-					if (SessionVariablesUtil.isScreenClient(client)) {
-						// screen sharing clients do not receive events
-						continue;
-					}
-
-					((IServiceCapableConnection) conn).invoke("interviewStatus", new Object[] { interviewStatus }, this);
-					log.debug("-- startInterviewRecording " + interviewStatus);
-				}
-			}
-			String recordingName = "Interview " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
-
-			recordingService.recordMeetingStream(current, current_rcl, recordingName, "", true);
-
-			return true;
-		} catch (Exception err) {
-			log.debug("[startInterviewRecording]", err);
-		}
-		return false;
-	}
-
-	@SuppressWarnings({ "rawtypes" })
-	public boolean sendRemoteCursorEvent(final String streamid, Map messageObj) {
-		new MessageSender("sendRemoteCursorEvent", messageObj, this) {
-
-			@Override
-			public boolean filter(IConnection conn) {
-				IClient client = conn.getClient();
-				return !SessionVariablesUtil.isScreenClient(client) || !conn.getClient().getId().equals(streamid);
-			}
-		}.start();
-		return true;
-	}
-
-	private Long checkRecordingClient(IConnection conn) {
-		Long recordingId = null;
-		if (conn != null) {
-			Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-			if (rcl != null && rcl.getIsRecording()) {
-				rcl.setIsRecording(false);
-				recordingId = rcl.getRecordingId();
-				rcl.setRecordingId(null);
-
-				// Reset the Recording Flag to Record all
-				// Participants that enter later
-				sessionManager.updateClientByStreamId(conn.getClient().getId(), rcl, false, null);
-			}
-		}
-		return recordingId;
-	}
-
-	/**
-	 * Stop the recording of the streams and send event to connected users of scope
-	 *
-	 * @return true if interview was found
-	 */
-	public boolean stopInterviewRecording() {
-		IConnection current = Red5.getConnectionLocal();
-		Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-		return _stopInterviewRecording(currentClient, current.getScope());
-	}
-
-	/**
-	 * Stop the recording of the streams and send event to connected users of scope
-	 *
-	 * @return true if interview was found
-	 */
-	private boolean _stopInterviewRecording(Client currentClient, IScope currentScope) {
-		try {
-			log.debug("-----------  stopInterviewRecording");
-			Long clientRecordingId = currentClient.getRecordingId();
-
-			for (IConnection conn : currentScope.getClientConnections()) {
-				Long recordingId = checkRecordingClient(conn);
-				if (recordingId != null) {
-					clientRecordingId = recordingId;
-				}
-			}
-			if (clientRecordingId == null) {
-				log.debug("stopInterviewRecording:: unable to find recording client");
-				return false;
-			}
-
-			recordingService.stopRecordAndSave(scope, currentClient, clientRecordingId);
-
-			Map<String, String> interviewStatus = new HashMap<>();
-			interviewStatus.put("action", "stop");
-
-			sendMessageToCurrentScope("interviewStatus", interviewStatus, true);
-			return true;
-
-		} catch (Exception err) {
-			log.debug("[stopInterviewRecording]", err);
-		}
-		return false;
-	}
-
-	/**
-	 * Get all ClientList Objects of that room and domain Used in
-	 * lz.applyForModeration.lzx
-	 *
-	 * @return all ClientList Objects of that room
-	 */
-	public List<Client> getClientListScope() {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-
-			return sessionManager.getClientListByRoom(currentClient.getRoomId());
-		} catch (Exception err) {
-			log.debug("[getClientListScope]", err);
-		}
-		return new ArrayList<>();
-	}
-
-	public String getCryptKey() {
-		return cfgDao.getCryptKey();
-	}
-
-	public IScope getRoomScope(String room) {
-		if (Strings.isEmpty(room)) {
-			return null;
-		} else {
-			IScope globalScope = getContext().getGlobalScope();
-			IScope webAppKeyScope = globalScope.getScope(OpenmeetingsVariables.webAppRootKey);
-
-			return webAppKeyScope.getScope(room);
-		}
-	}
-
-	/*
-	 * SIP transport methods
-	 */
-
-	private List<Long> getVerifiedActiveRoomIds(Server s) {
-		List<Long> result = new ArrayList<>(sessionManager.getActiveRoomIdsByServer(s));
-		//verify
-		for (Iterator<Long> i = result.iterator(); i.hasNext();) {
-			Long id = i.next();
-			List<Client> rcs = sessionManager.getClientListByRoom(id);
-			if (rcs.size() == 0 || (rcs.size() == 1 && rcs.get(0).isSipTransport())) {
-				i.remove();
-			}
-		}
-		return result.isEmpty() ? result : roomDao.getSipRooms(result);
-	}
-
-	public List<Long> getActiveRoomIds() {
-		List<Long> result = getVerifiedActiveRoomIds(null);
-		for (Server s : serverDao.getActiveServers()) {
-			result.addAll(getVerifiedActiveRoomIds(s));
-		}
-		return result.isEmpty() ? result : roomDao.getSipRooms(result);
-	}
-
-	private String getSipTransportLastname(Long roomId) {
-		return getSipTransportLastname(roomManager.getSipConferenceMembersNumber(roomId));
-	}
-
-	private static String getSipTransportLastname(Integer c) {
-		return (c != null && c > 0) ? "(" + (c - 1) + ")" : "";
-	}
-
-	public synchronized int updateSipTransport() {
-		log.debug("-----------  updateSipTransport");
-		IConnection current = Red5.getConnectionLocal();
-		String streamid = current.getClient().getId();
-		Client client = sessionManager.getClientByStreamId(streamid, null);
-		Long roomId = client.getRoomId();
-		Integer count = roomManager.getSipConferenceMembersNumber(roomId);
-		String newNumber = getSipTransportLastname(count);
-		log.debug("getSipConferenceMembersNumber: " + newNumber);
-		if (!newNumber.equals(client.getLastname())) {
-			client.setLastname(newNumber);
-			sessionManager.updateClientByStreamId(streamid, client, false, null);
-			log.debug("updateSipTransport: {}, {}, {}, {}, {}", new Object[] { client.getPublicSID(), client.getRoomId(),
-					client.getFirstname(), client.getLastname(), client.getAvsettings() });
-			sendMessageWithClient(new String[] { "personal", client.getFirstname(), client.getLastname() });
-		}
-		return count != null && count > 0 ? count - 1 : 0;
-	}
-
-	public void setSipTransport(Long roomId, String publicSID, String broadCastId) {
-		log.debug("-----------  setSipTransport");
-		IConnection current = Red5.getConnectionLocal();
-		IClient c = current.getClient();
-		String streamid = c.getId();
-		// Notify all clients of the same scope (room)
-		Client currentClient = sessionManager.getClientByStreamId(streamid, null);
-		currentClient.setSipTransport(true);
-		currentClient.setRoomId(roomId);
-		currentClient.setRoomEnter(new Date());
-		currentClient.setFirstname("SIP Transport");
-		currentClient.setLastname(getSipTransportLastname(roomId));
-		currentClient.setBroadCastID(Long.parseLong(broadCastId));
-		currentClient.setIsBroadcasting(true);
-		currentClient.setPublicSID(publicSID);
-		currentClient.setVWidth(120);
-		currentClient.setVHeight(90);
-		currentClient.setPicture_uri("phone.png");
-		sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-		SessionVariablesUtil.initClient(c, publicSID);
-
-		sendMessageToCurrentScope("addNewUser", currentClient, false);
-	}
-
-	public JSONObject getFlashSettings() {
-		return flashSettings;
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
index b02066f..a266a42 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
@@ -39,6 +39,7 @@ public interface IApplication {
 	String getOmString(long id, long languageId);
 	String getOmString(String key, long languageId);
 	String getOmString(String key, final Locale loc, String... params);
+	org.apache.openmeetings.db.entity.basic.Client getOmClient(String uid);
 	Client updateClient(Client rcl, boolean forceSize);
 	List<org.apache.openmeetings.db.entity.basic.Client> getOmRoomClients(Long roomId);
 	List<org.apache.openmeetings.db.entity.basic.Client> getOmClients(Long userId);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/Core.java
----------------------------------------------------------------------
diff --git a/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/Core.java b/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/Core.java
index defeadc..b0e8cde 100644
--- a/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/Core.java
+++ b/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/Core.java
@@ -67,12 +67,16 @@ public class Core implements IPendingServiceCallback, INetStreamEventHandler {
 	final static String QUARTZ_GROUP_NAME = "ScreenShare";
 	final static String QUARTZ_REMOTE_JOB_NAME = "RemoteJob";
 	final static String QUARTZ_REMOTE_TRIGGER_NAME = "RemoteTrigger";
+	private static final String CONNECT_REJECTED = "NetConnection.Connect.Rejected";
+	private static final String CONNECT_FAILED = "NetConnection.Connect.Failed";
 
 	enum Protocol {
 		rtmp, rtmpt, rtmpe, rtmps
 	}
 	private IScreenShare instance = null;
-	private Protocol protocol;
+	private URI url;
+	private URI fallback;
+	private boolean fallbackUsed = false;
 	private String host;
 	private String app;
 	private int port;
@@ -97,6 +101,7 @@ public class Core implements IPendingServiceCallback, INetStreamEventHandler {
 	private boolean readyToRecord = false;
 	private boolean audioNotify = false;
 	private boolean remoteEnabled = true;
+	private boolean nativeSsl = false;
 	private SchedulerFactory schdlrFactory;
 	private Scheduler schdlr;
 	private LinkedBlockingQueue<Map<String, Object>> remoteEvents = new LinkedBlockingQueue<>();
@@ -121,20 +126,17 @@ public class Core implements IPendingServiceCallback, INetStreamEventHandler {
 			}
 			String[] textArray = null;
 			if (args.length > 8) {
-				String _url = args[0];
-				URI url = new URI(_url);
-				protocol = Protocol.valueOf(url.getScheme());
-				host = url.getHost();
-				port = url.getPort();
-				app = url.getPath().substring(1);
-				publishName = args[1];
-				String labelTexts = args[2];
-				defaultQuality = Integer.parseInt(args[3]);
-				defaultFPS = Integer.parseInt(args[4]);
-				showFPS = bool(args[5]);
-				remoteEnabled = bool(args[6]);
-				allowRecording = bool(args[7]);
-				allowPublishing = bool(args[8]);
+				url = new URI(args[0]);
+				fallback = new URI(args[1]);
+				publishName = args[2];
+				String labelTexts = args[3];
+				defaultQuality = Integer.parseInt(args[4]);
+				defaultFPS = Integer.parseInt(args[5]);
+				showFPS = bool(args[6]);
+				remoteEnabled = bool(args[7]);
+				allowRecording = bool(args[8]);
+				allowPublishing = bool(args[9]);
+				nativeSsl = bool(args[10]);
 
 				if (labelTexts.length() > 0) {
 					textArray = labelTexts.split(";");
@@ -145,30 +147,6 @@ public class Core implements IPendingServiceCallback, INetStreamEventHandler {
 						log.debug(i + " :: " + textArray[i]);
 					}
 				}
-				switch (protocol) {
-					case rtmp:
-						instance = new RTMPScreenShare(this);
-						break;
-					case rtmpt:
-						instance = new RTMPTScreenShare(this);
-						break;
-					case rtmps:
-						boolean nativeSsl = bool(args[9]);
-						if (nativeSsl) {
-							RTMPSScreenShare client = new RTMPSScreenShare(this);
-							//NOT in use since 1.0.8-M3 client.setKeystoreBytes(Hex.decodeHex(args[10].toCharArray()));
-							client.setKeyStorePassword(args[11]);
-							instance = client;
-						} else {
-							instance = new RTMPTSScreenShare(this);
-						}
-						break;
-					case rtmpe:
-					default:
-						throw new Exception("Unsupported protocol");
-				}
-				instance.setServiceProvider(this);
-				log.debug(String.format("host: %s, port: %s, app: %s, publish: %s", host, port, app, publishName));
 			} else {
 				System.exit(0);
 			}
@@ -188,6 +166,35 @@ public class Core implements IPendingServiceCallback, INetStreamEventHandler {
 		}
 	}
 
+	private void setInstance(URI uri) {
+		Protocol protocol = Protocol.valueOf(uri.getScheme());
+		host = uri.getHost();
+		port = uri.getPort();
+		app = uri.getPath().substring(1);
+
+		switch (protocol) {
+			case rtmp:
+				instance = new RTMPScreenShare(this);
+				break;
+			case rtmpt:
+				instance = new RTMPTScreenShare(this);
+				break;
+			case rtmps:
+				if (nativeSsl) {
+					RTMPSScreenShare client = new RTMPSScreenShare(this);
+					instance = client;
+				} else {
+					instance = new RTMPTSScreenShare(this);
+				}
+				break;
+			case rtmpe:
+			default:
+				throw new RuntimeException("Unsupported protocol");
+		}
+		instance.setServiceProvider(this);
+		log.debug(String.format("host: %s, port: %s, app: %s, publish: %s", host, port, app, publishName));
+	}
+
 	@SuppressWarnings("unused")
 	public static void main(String[] args) {
 		new Core(args);
@@ -298,10 +305,12 @@ public class Core implements IPendingServiceCallback, INetStreamEventHandler {
 	}
 
 	private void connect(String parentSid) {
+		setInstance(fallbackUsed ? fallback : url);
 		Map<String, Object> map = instance.makeDefaultConnectionParams(host, port, app);
 		map.put("screenClient", true);
-		map.put("parentSid", parentSid);
-		instance.connect(host, port, map, this);
+		Map<String, Object> params = new HashMap<>();
+		params.put("uid", parentSid);
+		instance.connect(host, port, map, this, new Object[]{params});
 	}
 
 	private void captureScreenStart() {
@@ -491,7 +500,13 @@ public class Core implements IPendingServiceCallback, INetStreamEventHandler {
 			log.trace("call ### get Method Name " + method);
 			if ("connect".equals(method)) {
 				Object code = returnMap.get("code");
-				if ("NetConnection.Connect.Rejected".equals(code) || "NetConnection.Connect.Failed".equals(code)) {
+				if (CONNECT_FAILED.equals(code) && !fallbackUsed) {
+					fallbackUsed = true;
+					connect(publishName);
+					frame.setStatus("Re-connecting using fallback");
+					return;
+				}
+				if (CONNECT_FAILED.equals(code) || CONNECT_REJECTED.equals(code)) {
 					frame.setStatus(String.format("Error: %s %s", code, returnMap.get("description")));
 					return;
 				}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/IScreenShare.java
----------------------------------------------------------------------
diff --git a/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/IScreenShare.java b/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/IScreenShare.java
index 594a1ea..760d5e9 100644
--- a/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/IScreenShare.java
+++ b/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screenshare/IScreenShare.java
@@ -30,7 +30,7 @@ public interface IScreenShare extends ClientExceptionHandler {
 	RTMPConnection getConnection();
 	void invoke(String method, Object[] params, IPendingServiceCallback callback);
 	Map<String, Object> makeDefaultConnectionParams(String server, int port, String application);
-	void connect(String server, int port, Map<String, Object> connectionParams, IPendingServiceCallback connectCallback);
+	void connect(String server, int port, Map<String, Object> connectionParams, IPendingServiceCallback connectCallback, Object[] connectCallArguments);
 	void setServiceProvider(Object serviceProvider);
 	void disconnect();
 	void createStream(IPendingServiceCallback callback);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-screenshare/src/main/jnlp/templates/template.jnlp
----------------------------------------------------------------------
diff --git a/openmeetings-screenshare/src/main/jnlp/templates/template.jnlp b/openmeetings-screenshare/src/main/jnlp/templates/template.jnlp
index c2a9e01..2e1c9f8 100644
--- a/openmeetings-screenshare/src/main/jnlp/templates/template.jnlp
+++ b/openmeetings-screenshare/src/main/jnlp/templates/template.jnlp
@@ -38,6 +38,7 @@
 	</resources>
 	<application-desc main-class='org.apache.openmeetings.screenshare.Core'>
 		<argument>$url</argument>
+		<argument>$fallback</argument>
 		<argument>$publicSid</argument>
 		<argument>$labels</argument>
 		<argument>$defaultQuality</argument>
@@ -47,7 +48,5 @@
 		<argument>$allowRecording</argument>
 		<argument>$allowPublishing</argument>
 		<argument>$native</argument>
-		<argument>$keystore</argument>
-		<argument>$password</argument>
 	</application-desc>
 </jnlp>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
index d52cba1..37f8d92 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
@@ -43,7 +43,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.persistence.TypedQuery;
 
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
 import org.apache.openmeetings.db.dao.server.ISessionManager;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
----------------------------------------------------------------------
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
index c931b61..63410f4 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
@@ -47,6 +47,8 @@ public class RoomMessage implements IWebSocketPushMessage {
 		, requestRightExclusive
 		, haveQuestion
 		, kick
+		, newStream
+		, closeStream
 	}
 	private final Date timestamp;
 	private final String uid;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 271f119..ac7cfa8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -42,7 +42,7 @@ import java.util.function.Predicate;
 import org.apache.directory.api.util.Strings;
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.remote.MainService;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
@@ -632,4 +632,9 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	public String getOmString(String key, final Locale loc, String... params) {
 		return getString(key, loc, params);
 	}
+
+	@Override
+	public Client getOmClient(String uid) {
+		return getOnlineClient(uid);
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
index b4da5e9..1527797 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
@@ -116,7 +116,7 @@ public class MainPanel extends Panel {
 		@Override
 		protected void onTimer(AjaxRequestTarget target) {
 			log.debug("Sending WebSocket PING");
-			WebSocketHelper.sendClient(client, new byte[1]);
+			WebSocketHelper.sendClient(client, new byte[]{getUserId().byteValue()});
 		}
 	};
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
index 819a877..17a0a57 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
@@ -21,7 +21,7 @@ package org.apache.openmeetings.web.room;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.session.SessionManager;
 import org.apache.openmeetings.db.dto.server.ClientSessionInfo;
 import org.apache.openmeetings.db.entity.room.Client;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index abb98dc..add92fc 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -368,6 +368,27 @@ public class RoomPanel extends BasePanel {
 							wb.update(handler);
 						}
 						break;
+					case newStream:
+					{
+						JSONObject obj = new JSONObject(((TextRoomMessage)m).getText());
+						Client c = getOnlineClient(obj.getString("uid"));
+						boolean self = getClient().getUid().equals(c.getUid());
+						if (!self) {
+							JSONObject json = c.toJson().put("sid", getSid()).put("self", self);
+							if (obj.optBoolean("screenShare", false)) {
+								json.put("screenShare", true)
+									.put("uid", obj.getString("suid")) // unique screen-sharing ID
+									.put("broadcastId", obj.getString("broadcastId"))
+									.put("width", obj.getInt("width"))
+									.put("height", obj.getInt("height"));
+							}
+							handler.appendJavaScript(String.format("VideoManager.play(%s);", json));
+						}
+					}
+						break;
+					case closeStream:
+						handler.appendJavaScript(String.format("VideoManager.close('%s');", ((TextRoomMessage)m).getText()));
+						break;
 					case roomEnter:
 						sidebar.update(handler);
 						menu.update(handler);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
index b8a55bf..23c03b0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
@@ -18,17 +18,17 @@
  */
 package org.apache.openmeetings.web.room;
 
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_NATIVE_SSL;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_PORT;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SECURE;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SSL_PORT;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_NATIVE_SSL;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_PORT;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_SECURE;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_SSL_PORT;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.wicket.RuntimeConfigurationType.DEVELOPMENT;
 
 import java.net.URL;
 
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.common.BasePanel;
 import org.apache.openmeetings.web.common.OmAjaxClientInfoBehavior;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
index fad5838..0e39518 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
@@ -18,19 +18,19 @@
  */
 package org.apache.openmeetings.web.room;
 
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_FPS;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_NATIVE_SSL;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_PORT;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SECURE;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SSL_PORT;
-import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_VIDEO_CODEC;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_FPS;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_NATIVE_SSL;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_PORT;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_SECURE;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_SSL_PORT;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_VIDEO_CODEC;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 
 import java.net.URL;
 
 import org.apache.directory.api.util.Strings;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.markup.head.IHeaderResponse;
@@ -48,8 +48,8 @@ public class VideoSettings extends Panel {
 	private final static long serialVersionUID = 1L;
 	private final static Logger log = Red5LoggerFactory.getLogger(VideoSettings.class, webAppRootKey);
 	private final static ResourceReference SETTINGS_JS_REFERENCE = new JavaScriptResourceReference(VideoSettings.class, "settings.js");
-	private final static String URL = "url";
-	private final static String FALLBACK = "fallback";
+	public final static String URL = "url";
+	public final static String FALLBACK = "fallback";
 
 	public VideoSettings(String id) {
 		super(id);
@@ -79,8 +79,8 @@ public class VideoSettings extends Panel {
 			URL url = new URL(cp.getCodebase());
 			String path = url.getPath();
 			path = path.substring(1, path.indexOf('/', 2) + 1) + scope;
+			s.put(FLASH_NATIVE_SSL, gs.getBoolean(FLASH_NATIVE_SSL));
 			if (gs.getBoolean(FLASH_SECURE)) {
-				s.put(FLASH_NATIVE_SSL, gs.getBoolean(FLASH_NATIVE_SSL));
 				s.put(URL, getUri("rtmps", url.getHost(), gs.getString(FLASH_SSL_PORT), path));
 				s.put(FALLBACK, getUri("rtmps", url.getHost(), url.getPort(), path));
 			} else {


[44/50] [abbrv] openmeetings git commit: no jira: instructions updated according to board comments

Posted by so...@apache.org.
no jira: instructions updated according to board comments


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/a4d2a564
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/a4d2a564
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/a4d2a564

Branch: refs/heads/master
Commit: a4d2a5640015d6c9487de5080aa658fe8283e8c6
Parents: c744c8b
Author: Maxim Solodovnik <so...@apache.org>
Authored: Thu Apr 20 01:40:00 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Thu Apr 20 01:40:00 2017 +0000

----------------------------------------------------------------------
 openmeetings-server/src/site/xdoc/ReleaseGuide.xml | 4 ----
 1 file changed, 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a4d2a564/openmeetings-server/src/site/xdoc/ReleaseGuide.xml
----------------------------------------------------------------------
diff --git a/openmeetings-server/src/site/xdoc/ReleaseGuide.xml b/openmeetings-server/src/site/xdoc/ReleaseGuide.xml
index 4015a08..b1227ec 100644
--- a/openmeetings-server/src/site/xdoc/ReleaseGuide.xml
+++ b/openmeetings-server/src/site/xdoc/ReleaseGuide.xml
@@ -187,16 +187,12 @@ mvn deploy -Pdeploy,rc
 					<a href="http://mail-archives.apache.org/mod_mbox/openmeetings-dev/201701.mbox/%3CCAJmbs8jZ7EiXoeBbG4ynvg30FPx2nAOJMypE2Qp-v-c63ayO9A%40mail.gmail.com%3E">example Vote email</a>
 					<a href="http://s.apache.org/vote-2.0.0RC4">example Vote email (Incubator)</a>
 					<br />
-					Forward (Not CC) this Vote email to: private@openmeetings.apache.org<br />
-					<br />
 					After the vote is over, send a "RESULT" email to the list with the subject line:<br />
 					[RESULT][VOTE] Apache OpenMeetings x.xx release<br />
 					An example for such an email:
 					<a
 						href="http://mail-archives.apache.org/mod_mbox/openmeetings-dev/201701.mbox/%3CCAJmbs8gyvHuarzdVma%2BF6ap7RHBhhVciZp5Oi5JogQdLR6o0NA%40mail.gmail.com%3E">example Result email</a>
 					<br />
-					Forward (Not CC) this RESULT VOTE email to: private@openmeetings.apache.org<br />
-					<br />
 					Votes on whether a package is ready to be released use majority approval -- i.e., at 
 					least three PMC members must vote affirmatively for release, and there must be more 
 					positive than negative votes. Releases may not be vetoed. Before voting +1 PMC members


[34/50] [abbrv] openmeetings git commit: OPENMEETINGS-551 - The video frames from other participants are shown when the new participant enter to the room.

Posted by so...@apache.org.
OPENMEETINGS-551 - The video frames from other participants are shown when the new participant enter to the room.


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/1b9cde02
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/1b9cde02
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/1b9cde02

Branch: refs/heads/master
Commit: 1b9cde0269ff0be145e1f1faf0a4c3c53d1b24f3
Parents: ad9b33b
Author: Vasiliy Degtyarev <vd...@apache.org>
Authored: Tue Apr 18 09:30:58 2017 +0000
Committer: Vasiliy Degtyarev <vd...@apache.org>
Committed: Tue Apr 18 09:30:58 2017 +0000

----------------------------------------------------------------------
 .../apache/openmeetings/web/room/RoomPanel.java  | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/1b9cde02/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index add92fc..8c2497f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -122,6 +122,8 @@ public class RoomPanel extends BasePanel {
 			options.put("interview", Room.Type.interview == r.getType());
 			target.appendJavaScript(String.format("VideoManager.init(%s);", options));
 			WebSocketHelper.sendRoom(new RoomMessage(r.getId(), getUserId(), RoomMessage.Type.roomEnter));
+			// play video from other participants
+			playVideos(target);
 			getMainPanel().getChat().roomEnter(r, target);
 			if (r.isFilesOpened()) {
 				sidebar.setFilesActive(target);
@@ -156,6 +158,23 @@ public class RoomPanel extends BasePanel {
 		//private String publishingUser = null;
 	}
 
+	private void playVideos(AjaxRequestTarget target) {
+		for (Client c: getRoomClients(getRoom().getId()) ){
+			boolean self = getClient().getUid().equals(c.getUid());
+			if (!self) {
+				JSONObject json = c.toJson().put("sid", getSid()).put("self", self);
+				json.put("screenShare", false)
+					.put("uid", c.getUid())
+					.put("broadcastId", c.getBroadcastId())
+					.put("width", c.getWidth())
+					.put("height", c.getHeight());
+				target.appendJavaScript(String.format("VideoManager.play(%s);", json));
+			}
+			
+		}
+		
+	}
+	
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();


[25/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] hash?swf=settings is fixed, code clean-up

Posted by so...@apache.org.
[OPENMEETINGS-551] hash?swf=settings is fixed, code clean-up


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/b1c60093
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/b1c60093
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/b1c60093

Branch: refs/heads/master
Commit: b1c600933eeb725440d5e30f73afb5f7bd5aa14d
Parents: b27ea43
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 12 17:17:42 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 12 17:17:42 2017 +0000

----------------------------------------------------------------------
 .../core/data/whiteboard/WhiteboardManager.java | 135 ----------
 .../core/remote/ConferenceLibrary.java          |  63 -----
 .../openmeetings/core/remote/MainService.java   | 165 ------------
 .../remote/red5/ScopeApplicationAdapter.java    | 242 +----------------
 .../openmeetings/db/util/ApplicationHelper.java |   2 +-
 .../flex/org/apache/openmeetings/OmVideo.as     |  11 +-
 .../src/site/xdoc/Clustering.xml                |   2 +-
 .../src/site/xdoc/voip-sip-integration.xml      |   5 +-
 .../openmeetings/web/app/Application.java       |   6 +-
 .../apache/openmeetings/web/pages/HashPage.java |  26 +-
 .../apache/openmeetings/web/room/RoomPanel.java |  32 +--
 .../openmeetings/web/room/VideoSettings.html    |  90 +++++++
 .../openmeetings/web/room/VideoSettings.java    |  95 +++++++
 .../org/apache/openmeetings/web/room/room.js    | 163 ------------
 .../apache/openmeetings/web/room/settings.js    | 179 +++++++++++++
 .../web/room/sidebar/RoomSidebar.html           |  67 +----
 .../web/room/sidebar/RoomSidebar.java           |   6 +-
 .../WEB-INF/classes/applicationContext.xml      | 260 ++++++++++++++++++
 .../classes/openmeetings-applicationContext.xml | 261 -------------------
 .../src/main/webapp/WEB-INF/red5-web.xml        |   2 +-
 .../src/main/webapp/WEB-INF/web.xml             |   2 +-
 .../openmeetings/test/AbstractSpringTest.java   |   2 +-
 pom.xml                                         |   2 +-
 23 files changed, 682 insertions(+), 1136 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/whiteboard/WhiteboardManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/whiteboard/WhiteboardManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/whiteboard/WhiteboardManager.java
deleted file mode 100644
index 2154b96..0000000
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/data/whiteboard/WhiteboardManager.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.core.data.whiteboard;
-
-import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
-
-import java.util.Map;
-
-import org.red5.logging.Red5LoggerFactory;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class WhiteboardManager {
-	private static final Logger log = Red5LoggerFactory.getLogger(WhiteboardManager.class, webAppRootKey);
-
-	@Autowired
-	private WhiteboardCache whitebardCache;
-
-	@SuppressWarnings("unchecked")
-	public void add(Long roomId, Map<Integer, Object> whiteboardObj, Long whiteBoardId) {
-		/* FIXME TODO check this
-		try {
-			log.debug("add: ", whiteboardObj);
-
-			String action = whiteboardObj.get(2).toString();
-
-			log.debug("action: " + action);
-			log.debug("actionObject: " + whiteboardObj.get(3));
-
-			List<Object> actionObject = (List<Object>) whiteboardObj.get(3);
-
-			Whiteboard wb = whitebardCache.get(roomId, whiteBoardId);
-			if (action.equals("moveMap")) {
-				wb.setX(Integer.valueOf(actionObject.get(1).toString()));
-				wb.setY(Integer.valueOf(actionObject.get(2).toString()));
-			} else if (action.equals("draw") || action.equals("redo")) {
-				// log.debug(actionObject);
-				// log.debug(actionObject.size()-1);
-				// log.debug(actionObject.get(actionObject.size()-1));
-				if (actionObject != null && !actionObject.isEmpty()) {
-					String objectType = actionObject.get(0).toString();
-					if (!objectType.equals("pointerWhiteBoard")) {
-						String objectOID = actionObject.get(actionObject.size() - 1).toString();
-						log.debug("objectOID: " + objectOID);
-						wb.add(objectOID, actionObject);
-					}
-				}
-			} else if (action.equals("clear")) {
-				wb.clear();
-			} else if (action.equals("delete") || action.equals("undo")) {
-				wb.remove(actionObject);
-			} else if (action.equals("size") || action.equals("editProp")
-					|| action.equals("editTextMindMapNode")
-					|| action.equals("editText") || action.equals("swf")
-					|| action.equals("flv")
-					|| action.equals("editTextMindMapColor")
-					|| action.equals("editTextMindMapFontColor")) {
-				String objectOID = actionObject.get(actionObject.size() - 1).toString();
-				// List roomItem = roomList.get(objectOID);
-				List<Object> currentObject = wb.get(objectOID);
-				if ("paint".equals(actionObject.get(0))) {
-					actionObject.set(1, currentObject.get(1));
-				}
-				wb.add(objectOID, actionObject);
-
-				if (action.equals("swf")) {
-					log.debug("actionObject " + actionObject);
-					if (actionObject.get(0).equals("swf")) {
-						if (actionObject.get(8) != currentObject.get(8)) {
-							String baseObjectName = actionObject.get(actionObject.size() - 1).toString();
-							Integer slidesNumber = Integer.valueOf(actionObject.get(8).toString());
-
-							log.debug("updateObjectsToSlideNumber :: " + baseObjectName + "," + slidesNumber);
-
-							for (Entry<String, List<Object>> me : wb.entrySet()) {
-								List<Object> actionObjectStored = me.getValue();
-
-								if (actionObjectStored.get(0).equals("ellipse")
-										|| actionObjectStored.get(0).equals("drawarrow")
-										|| actionObjectStored.get(0).equals("line")
-										|| actionObjectStored.get(0).equals("clipart")
-										|| actionObjectStored.get(0).equals("paint")
-										|| actionObjectStored.get(0).equals("rectangle")
-										|| actionObjectStored.get(0).equals("uline")
-										|| actionObjectStored.get(0).equals("image")
-										|| actionObjectStored.get(0).equals("letter")) {
-
-									Map<String, Object> swfObj = (Map<String, Object>) actionObjectStored.get(actionObjectStored.size() - 7);
-									log.debug("swfObj :1: " + swfObj);
-
-									if (swfObj != null) {
-										if (swfObj.get("name").equals(baseObjectName)) {
-											swfObj.put("isVisible", Integer.parseInt(swfObj.get("slide").toString()) == slidesNumber);
-											actionObjectStored.set(actionObjectStored.size() - 7, swfObj);
-										}
-									}
-
-									log.debug("swfObj :1: " + swfObj);
-								}
-							}
-						}
-					}
-				}
-			} else if (action.equals("clearSlide")) {
-				for (Object objectName : actionObject) {
-					wb.remove(objectName);
-				}
-			} else if (action.equals("whiteboardObj")) {
-				wb.setFullFit((Boolean) actionObject.get(1));
-				wb.setZoom((Integer) actionObject.get(2));
-			} else {
-				log.warn("Unkown Type: " + action + " actionObject: " + actionObject);
-			}
-		} catch (Exception err) {
-			log.error("[add]", err);
-		}
-		*/
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceLibrary.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceLibrary.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceLibrary.java
index 58c6350..230cc89 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceLibrary.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceLibrary.java
@@ -21,24 +21,14 @@ package org.apache.openmeetings.core.remote;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
-import org.apache.openmeetings.core.data.whiteboard.WhiteboardManager;
 import org.apache.openmeetings.core.documents.LibraryChartLoader;
 import org.apache.openmeetings.core.documents.LibraryDocumentConverter;
-import org.apache.openmeetings.core.documents.LibraryWmlLoader;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.dao.file.FileExplorerItemDao;
-import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.dto.server.ClientSessionInfo;
 import org.apache.openmeetings.db.entity.file.FileExplorerItem;
-import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.db.entity.file.FileItem.Type;
-import org.apache.openmeetings.db.entity.room.Client;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
 import org.apache.openmeetings.util.OmFileHelper;
@@ -57,17 +47,11 @@ public class ConferenceLibrary implements IPendingServiceCallback {
 	private static final Logger log = Red5LoggerFactory.getLogger(ConferenceLibrary.class, webAppRootKey);
 
 	@Autowired
-	private ISessionManager sessionManager;
-	@Autowired
 	private SessiondataDao sessionDao;
 	@Autowired
 	private UserDao userDao;
 	@Autowired
 	private FileExplorerItemDao fileDao;
-	@Autowired
-	private WhiteboardManager whiteboardManager;
-	@Autowired
-	private ScopeApplicationAdapter scopeAdapter;
 
 	/**
 	 *
@@ -106,53 +90,6 @@ public class ConferenceLibrary implements IPendingServiceCallback {
 	}
 
 	/**
-	 * Loads a Object from the library into the whiteboard of all participant of
-	 * the current room
-	 *
-	 * @param uid - uid of the client performing operation
-	 * @param wbId - id of whiteboard
-	 * @param fi - FileItem of the Wml being loaded
-	 */
-	public void sendToWhiteboard(String uid, Long wbId, FileItem fi) {
-		ClientSessionInfo csi = sessionManager.getClientByPublicSIDAnyServer(uid);
-		if (csi == null) {
-			log.warn("No client was found to send Wml:: {}", uid);
-			return;
-		}
-		Client client = csi.getRcl();
-
-		if (client == null) {
-			log.warn("No client was found to send Wml:: {}", uid);
-			return;
-		}
-
-		List<?> roomItems = LibraryWmlLoader.loadWmlFile(fi.getHash());
-
-		Map<Integer, Object> wbClear = new HashMap<>();
-		wbClear.put(2, "clear");
-		wbClear.put(3, null);
-
-		Long roomId = client.getRoomId();
-		whiteboardManager.add(roomId, wbClear, wbId);
-
-		for (int k = 0; k < roomItems.size(); k++) {
-			List<?> actionObject = (List<?>)roomItems.get(k);
-
-			Map<Integer, Object> whiteboardObj = new HashMap<>();
-			whiteboardObj.put(2, "draw");
-			whiteboardObj.put(3, actionObject);
-
-			whiteboardManager.add(roomId, whiteboardObj, wbId);
-		}
-
-		Map<String, Object> sendObject = new HashMap<>();
-		sendObject.put("id", wbId);
-		sendObject.put("roomitems", roomItems);
-
-		scopeAdapter.sendToScope(roomId, "loadWmlToWhiteboardById", sendObject);
-	}
-
-	/**
 	 *
 	 * Loads a chart object
 	 *

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MainService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MainService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MainService.java
index b16733d..74db960 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MainService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MainService.java
@@ -18,41 +18,15 @@
  */
 package org.apache.openmeetings.core.remote;
 
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_MAX_UPLOAD_SIZE_KEY;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_REDIRECT_URL_FOR_EXTERNAL_KEY;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SIP_ENABLED;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
-import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
-import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
-import org.apache.openmeetings.db.dao.log.ConferenceLogDao;
-import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.dao.server.ISessionManager;
-import org.apache.openmeetings.db.dao.server.SessiondataDao;
-import org.apache.openmeetings.db.dao.user.IUserManager;
-import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.entity.basic.Configuration;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
-import org.apache.openmeetings.db.entity.log.ConferenceLog;
-import org.apache.openmeetings.db.entity.room.Client;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.RoomGroup;
-import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.entity.user.User.Right;
-import org.apache.openmeetings.db.entity.user.Userdata;
-import org.apache.openmeetings.db.util.AuthLevelUtil;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.red5.logging.Red5LoggerFactory;
-import org.red5.server.api.IConnection;
-import org.red5.server.api.Red5;
 import org.red5.server.api.service.IPendingServiceCall;
 import org.red5.server.api.service.IPendingServiceCallback;
 import org.slf4j.Logger;
@@ -67,63 +41,11 @@ public class MainService implements IPendingServiceCallback {
 	private static final Logger log = Red5LoggerFactory.getLogger(MainService.class, OpenmeetingsVariables.webAppRootKey);
 
 	@Autowired
-	private ISessionManager sessionManager;
-	@Autowired
-	private ScopeApplicationAdapter scopeApplicationAdapter;
-	@Autowired
-	private SessiondataDao sessionDao;
-	@Autowired
-	private ConfigurationDao configurationDao;
-	@Autowired
-	private IUserManager userManager;
-	@Autowired
-	private ConferenceLogDao conferenceLogDao;
-	@Autowired
-	private UserDao userDao;
-	@Autowired
-	private RoomDao roomDao;
-	@Autowired
 	private AppointmentDao appointmentDao;
 
 	// External User Types
 	public static final String EXTERNAL_USER_TYPE_LDAP = "LDAP";
 
-
-	/**
-	 * gets a user by its SID
-	 *
-	 * @param sid
-	 * @param userId
-	 * @return - user with SID given
-	 */
-	public User getUser(String sid, long userId) {
-		User users = new User();
-		Sessiondata sd = sessionDao.check(sid);
-		Set<Right> rights = userDao.getRights(sd.getUserId());
-		if (AuthLevelUtil.hasAdminLevel(rights) || AuthLevelUtil.hasWebServiceLevel(rights)) {
-			users = userDao.get(userId);
-		} else {
-			users.setFirstname("No rights to do this");
-		}
-		return users;
-	}
-
-	public Client getCurrentRoomClient(String SID) {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			String streamid = current.getClient().getId();
-
-			log.debug("getCurrentRoomClient -1- " + SID);
-			log.debug("getCurrentRoomClient -2- " + streamid);
-
-			Client currentClient = sessionManager.getClientByStreamId(streamid, null);
-			return currentClient;
-		} catch (Exception err) {
-			log.error("[getCurrentRoomClient]", err);
-		}
-		return null;
-	}
-
 	public boolean isRoomAllowedToUser(Room r, User u) {
 		boolean allowed = false;
 		if (r != null) {
@@ -172,93 +94,6 @@ public class MainService implements IPendingServiceCallback {
 		return allowed;
 	}
 
-	public List<Object> loginWicket(String wicketSID, Long wicketroomid) {
-		log.debug("[loginWicket] wicketSID: '{}'; wicketroomid: '{}'", wicketSID, wicketroomid);
-		Sessiondata sd = sessionDao.check(wicketSID);
-		Long userId = sd.getUserId();
-		User u = userId == null ? null : userDao.get(userId);
-		Room r = roomDao.get(wicketroomid);
-		if (u != null && r != null) {
-			log.debug("[loginWicket] user and roomid are not empty: " + userId + ", " + wicketroomid);
-			if (wicketroomid.equals(sd.getRoomId()) || isRoomAllowedToUser(r, u)) {
-				IConnection current = Red5.getConnectionLocal();
-				String streamId = current.getClient().getId();
-				Client currentClient = sessionManager.getClientByStreamId(streamId, null);
-
-				if (User.Type.user != u.getType() || (User.Type.user == u.getType() && !u.getGroupUsers().isEmpty())) {
-					u.setSessionData(sd);
-					currentClient.setUserId(u.getId());
-					currentClient.setRoomId(wicketroomid);
-					SessionVariablesUtil.setUserId(current.getClient(), u.getId());
-
-					currentClient.setUsername(u.getLogin());
-					currentClient.setFirstname(u.getFirstname());
-					currentClient.setLastname(u.getLastname());
-					currentClient.setPicture_uri(u.getPictureuri());
-					currentClient.setEmail(u.getAddress() == null ? null : u.getAddress().getEmail());
-					sessionManager.updateClientByStreamId(streamId, currentClient, false, null);
-
-					scopeApplicationAdapter.sendMessageToCurrentScope("roomConnect", currentClient, false);
-
-					return Arrays.<Object>asList(u, r);
-				}
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Function is called if the user loggs in via a secureHash and sets the
-	 * param showNickNameDialog in the Object SOAPLogin to true the user gets
-	 * displayed an additional dialog to enter his nickname
-	 *
-	 * @param firstname
-	 * @param lastname
-	 * @param email
-	 * @return - 1 in case of success, -1 otherwise
-	 */
-	public Long setUserNickName(String firstname, String lastname, String email) {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			String streamId = current.getClient().getId();
-			Client currentClient = sessionManager.getClientByStreamId(streamId, null);
-
-			currentClient.setFirstname(firstname);
-			currentClient.setLastname(lastname);
-			currentClient.setEmail(email);
-
-			// Log the User
-			conferenceLogDao.add(
-					ConferenceLog.Type.nicknameEnter, currentClient.getUserId(), streamId,
-					null, currentClient.getUserip(), currentClient.getScope());
-
-			sessionManager.updateClientByStreamId(streamId, currentClient, false, null);
-			scopeApplicationAdapter.sendMessageToCurrentScope("nickNameSet", currentClient, true);
-
-			return 1L;
-		} catch (Exception err) {
-			log.error("[setUserNickName] ", err);
-		}
-		return new Long(-1);
-	}
-
-	public List<Configuration> getGeneralOptions() {
-		try {
-			return configurationDao.get("exclusive.audio.keycode", CONFIG_SIP_ENABLED, CONFIG_MAX_UPLOAD_SIZE_KEY, "mute.keycode", CONFIG_REDIRECT_URL_FOR_EXTERNAL_KEY);
-		} catch (Exception err) {
-			log.error("[getGeneralOptions]",err);
-		}
-		return null;
-	}
-
-	public List<Userdata> getUserdata(String sid) {
-		Sessiondata sd = sessionDao.check(sid);
-		if (AuthLevelUtil.hasUserLevel(userDao.getRights(sd.getUserId()))) {
-			return userManager.getUserdataDashBoard(sd.getUserId());
-		}
-		return null;
-	}
-
 	@Override
 	public void resultReceived(IPendingServiceCall arg0) {
 		log.debug("[resultReceived]" + arg0);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
index 6a44556..ab9d5ab 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
@@ -18,18 +18,15 @@
  */
 package org.apache.openmeetings.core.remote.red5;
 
-import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_SECURE_PROXY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_VIDEO_CODEC;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
-import java.awt.Point;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -42,11 +39,8 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.apache.commons.io.FileUtils;
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.data.conference.RoomManager;
-import org.apache.openmeetings.core.data.whiteboard.WhiteboardCache;
-import org.apache.openmeetings.core.data.whiteboard.WhiteboardManager;
 import org.apache.openmeetings.core.remote.RecordingService;
 import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
 import org.apache.openmeetings.core.util.WebSocketHelper;
@@ -62,8 +56,6 @@ import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.dto.room.BrowserStatus;
 import org.apache.openmeetings.db.dto.room.RoomStatus;
-import org.apache.openmeetings.db.dto.server.ClientSessionInfo;
-import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.db.entity.log.ConferenceLog;
 import org.apache.openmeetings.db.entity.room.Client;
 import org.apache.openmeetings.db.entity.room.Room;
@@ -105,15 +97,16 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	private static final String SECURITY_CODE_PARAM = "securityCode";
 	private static final String WIDTH_PARAM = "width";
 	private static final String HEIGHT_PARAM = "height";
-	private static final String NATIVE_SSL_PARAM = "nativeSsl";
+	public static final String FLASH_SECURE = "secure";
+	public static final String FLASH_NATIVE_SSL = "native";
+	public static final String FLASH_PORT = "rtmpPort";
+	public static final String FLASH_SSL_PORT = "rtmpsPort";
+	public static final String FLASH_VIDEO_CODEC = "videoCodec";
+	public static final String FLASH_FPS = "fps";
 
 	@Autowired
 	private ISessionManager sessionManager;
 	@Autowired
-	private WhiteboardManager whiteboardManager;
-	@Autowired
-	private WhiteboardCache whiteboardCache;
-	@Autowired
 	private RecordingService recordingService;
 	@Autowired
 	private ConfigurationDao cfgDao;
@@ -161,12 +154,12 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 				props.load(is);
 			}
 			flashSettings = new JSONObject()
-					.put("secure", "yes".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE, String.class, "no")))
-					.put("proxyType", cfgDao.getConfValue(CONFIG_FLASH_SECURE_PROXY, String.class, "none"))
-					.put("rtmpPort", props.getProperty("rtmp.port"))
-					.put("rtmpsPort", props.getProperty("rtmps.port"))
-					.put("videoCodec", cfgDao.getConfValue(CONFIG_FLASH_VIDEO_CODEC, String.class, "h263"))
-					.put("fps", cfgDao.getConfValue(OpenmeetingsVariables.CONFIG_FLASH_VIDEO_FPS, Integer.class, "30"))
+					.put(FLASH_SECURE, "yes".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE, String.class, "no")))
+					.put(FLASH_NATIVE_SSL, "best".equals(cfgDao.getConfValue(CONFIG_FLASH_SECURE_PROXY, String.class, "none")))
+					.put(FLASH_PORT, props.getProperty("rtmp.port"))
+					.put(FLASH_SSL_PORT, props.getProperty("rtmps.port"))
+					.put(FLASH_VIDEO_CODEC, cfgDao.getConfValue(CONFIG_FLASH_VIDEO_CODEC, String.class, "h263"))
+					.put(FLASH_FPS, cfgDao.getConfValue(OpenmeetingsVariables.CONFIG_FLASH_VIDEO_FPS, Integer.class, "30"))
 					;
 
 			for (String scopeName : scope.getScopeNames()) {
@@ -307,7 +300,6 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		rcm.setUserip(conn.getRemoteAddress());
 		rcm.setSwfurl(swfURL);
 		rcm.setTcUrl(tcUrl);
-		rcm.setNativeSsl(Boolean.TRUE.equals(connParams.get(NATIVE_SSL_PARAM)));
 		if (!Strings.isEmpty(uid)) {
 			rcm.setPublicSID(uid);
 		}
@@ -1151,212 +1143,6 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		return null;
 	}
 
-	/**
-	 * This Function is triggered from the Whiteboard
-	 *
-	 * @param whiteboardObjParam - array of parameters being sended to whiteboard
-	 * @param whiteboardId - id of whiteboard parameters will be send to
-	 * @return 1 in case of no errors, -1 otherwise
-	 */
-	public int sendVarsByWhiteboardId(List<?> whiteboardObjParam, Long whiteboardId) {
-		try {
-			IConnection current = Red5.getConnectionLocal();
-			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-			return sendToWhiteboard(client, whiteboardObjParam, whiteboardId);
-		} catch (Exception err) {
-			log.error("[sendVarsByWhiteboardId]", err);
-			return -1;
-		}
-	}
-
-	private static Point getSize(FileItem fi) {
-		Point result = new Point(0, 0);
-		if (fi.getWidth() != null && fi.getHeight() != null) {
-			result.x = fi.getWidth();
-			result.y = fi.getHeight();
-		}
-		return result;
-	}
-
-	private static List<?> getWbObject(FileItem fi, String url) {
-		Point size = getSize(fi);
-		String type = "n/a";
-		switch (fi.getType()) {
-			case Image:
-				type = "image";
-				break;
-			case Presentation:
-				type = "swf";
-				break;
-			default:
-		}
-		return Arrays.asList(
-				type // 0
-				, url // urlname
-				, "--dummy--" // baseurl
-				, fi.getName() // fileName //3
-				, "--dummy--" // moduleName //4
-				, "--dummy--" // parentPath //5
-				, "--dummy--" // room //6
-				, "--dummy--" // domain //7
-				, 1 // slideNumber //8
-				, 0 // innerx //9
-				, 0 // innery //10
-				, size.x // innerwidth //11
-				, size.y // innerheight //12
-				, 20 // zoomlevel //13
-				, size.x // initwidth //14
-				, size.y // initheight //15
-				, 100 // currentzoom //16 FIXME TODO
-				, fi.getHash() // uniquObjectSyncName //17
-				, fi.getName() // standardFileName //18
-				, true // fullFit //19 FIXME TODO
-				, 0 // zIndex //-8
-				, null //-7
-				, 0 // this.counter //-6 FIXME TODO
-				, 0 // posx //-5
-				, 0 // posy //-4
-				, size.x // width //-3
-				, size.y // height //-2
-				, fi.getHash() // this.currentlayer.name //-1
-				);
-	}
-
-	private static List<?> getMp4WbObject(FileItem fi, String url) {
-		Point size = getSize(fi);
-		return Arrays.asList(
-				"flv" // 0: 'flv'
-				, fi.getId() // 1: 7
-				, fi.getName() // 2: 'BigBuckBunny_512kb.mp4'
-				, url // 3: posterUrl
-				, size.x // 4: 416
-				, size.y // 5: 240
-				, 0 // 6: 1 // z-index
-				, fi.getHash() // 7: null //TODO
-				, 0 // 8: 0 //TODO // counter
-				, 0 // 9: 0 //TODO // x
-				, 0 // 10: 0 //TODO // y
-				, size.x // 11: 749 // width
-				, size.y // 12: 739 // height
-				, fi.getHash() // 13: 'flv_1469602000351'
-				);
-	}
-
-	private static void copyFileToRoom(Long roomId, FileItem f) {
-		try {
-			if (roomId != null && f != null) {
-				File mp4 = f.getFile(EXTENSION_MP4);
-
-				File targetFolder = OmFileHelper.getStreamsSubDir(roomId);
-
-				File target = new File(targetFolder, mp4.getName());
-				if (mp4.exists() && !target.exists()) {
-					FileUtils.copyFile(mp4, target, false);
-				}
-			}
-		} catch (Exception err) {
-			log.error("[copyFileToCurrentRoom] ", err);
-		}
-	}
-
-	public void sendToWhiteboard(String uid, Long wbId, FileItem fi, String url, boolean clean) {
-		ClientSessionInfo csi = sessionManager.getClientByPublicSIDAnyServer(uid);
-		if (csi == null) {
-			log.warn("No client was found to send Wml:: {}", uid);
-			return;
-		}
-		Client client = csi.getRcl();
-
-		List<?> wbObject = new ArrayList<>();
-		switch (fi.getType()) {
-			case Image:
-				wbObject = getWbObject(fi, url);
-				break;
-			case Presentation:
-				wbObject = getWbObject(fi, url);
-				break;
-			case Video:
-			case Recording:
-				wbObject = getMp4WbObject(fi, url);
-				copyFileToRoom(client.getRoomId(), fi);
-				break;
-			default:
-		}
-		if (clean) {
-			Map<String, Object> wbClear = new HashMap<>();
-			wbClear.put("id", wbId);
-			wbClear.put("param", Arrays.asList("whiteboard", new Date(), "clear", null));
-
-			whiteboardCache.clear(client.getRoomId(), wbId);
-			sendToScope(client.getRoomId(), "sendVarsToWhiteboardById", Arrays.asList(null, wbClear));
-		}
-		sendToWhiteboard(client, Arrays.asList("whiteboard", new Date(), "draw", wbObject), wbId);
-	}
-
-	private int sendToWhiteboard(Client client, List<?> wbObj, Long wbId) {
-		try {
-			// Check if this User is the Mod:
-			if (client == null) {
-				return -1;
-			}
-
-			Map<Integer, Object> whiteboardObj = new HashMap<>();
-			int i = 0;
-			for (Object obj : wbObj) {
-				whiteboardObj.put(i++, obj);
-			}
-
-			Long roomId = client.getRoomId();
-
-			// log.debug("***** sendVars: " + whiteboardObj);
-
-			// Store event in list
-			String action = whiteboardObj.get(2).toString();
-
-			if (action.equals("deleteMindMapNodes")) {
-				// Simulate Single Delete Events for z-Index
-				List<?> actionObject = (List<?>) whiteboardObj.get(3);
-
-				@SuppressWarnings("unchecked")
-				List<List<?>> itemObjects = (List<List<?>>) actionObject.get(3);
-
-				Map<Integer, Object> whiteboardTempObj = new HashMap<>();
-				whiteboardTempObj.put(2, "delete");
-
-				for (List<?> itemObject : itemObjects) {
-					List<Object> tempActionObject = new ArrayList<>();
-					tempActionObject.add("mindmapnode");
-					tempActionObject.add(itemObject.get(0)); // z-Index -8
-					tempActionObject.add(null); // simulate -7
-					tempActionObject.add(null); // simulate -6
-					tempActionObject.add(null); // simulate -5
-					tempActionObject.add(null); // simulate -4
-					tempActionObject.add(null); // simulate -3
-					tempActionObject.add(null); // simulate -2
-					tempActionObject.add(itemObject.get(1)); // Object-Name -1
-
-					whiteboardTempObj.put(3, tempActionObject);
-
-					whiteboardManager.add(roomId, whiteboardTempObj, wbId);
-				}
-			} else {
-				whiteboardManager.add(roomId, whiteboardObj, wbId);
-			}
-
-			Map<String, Object> sendObject = new HashMap<>();
-			sendObject.put("id", wbId);
-			sendObject.put("param", wbObj);
-
-			boolean showDrawStatus = getWhiteboardDrawStatus();
-
-			sendToScope(roomId, "sendVarsToWhiteboardById", new Object[] { showDrawStatus ? client : null, sendObject });
-		} catch (Exception err) {
-			log.error("[sendToWhiteboard]", err);
-			return -1;
-		}
-		return 1;
-	}
-
 	public int sendMessage(Object newMessage) {
 		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
 		return 1;
@@ -1867,10 +1653,6 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		return new ArrayList<>();
 	}
 
-	private boolean getWhiteboardDrawStatus() {
-		return cfgDao.getWhiteboardDrawStatus();
-	}
-
 	public String getCryptKey() {
 		return cfgDao.getCryptKey();
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java
index 5079c61..c509be4 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java
@@ -100,7 +100,7 @@ public class ApplicationHelper {
 				OMContextListener omcl = new OMContextListener();
 				omcl.contextInitialized(new ServletContextEvent(sc));
 				XmlWebApplicationContext xmlContext = new XmlWebApplicationContext();
-				xmlContext.setConfigLocation("classpath:openmeetings-applicationContext.xml");
+				xmlContext.setConfigLocation("classpath:applicationContext.xml");
 				xmlContext.setServletContext(sc);
 				xmlContext.refresh();
 				sc.setAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, xmlContext);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
index 23eabbe..cbc0ffe 100644
--- a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
+++ b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
@@ -160,18 +160,9 @@ public class OmVideo {
 		}
 	}
 
-	private function getUrl():String {
-		var secure:Boolean = ('true' === params.secure);
-		var url:String = (secure ? "rtmps" : "rtmp") + "://"
-				+ params.host + ":" + (secure ? params.rtmpsPort : params.rtmpPort)
-				+ "/" + params.app;
-		//TODO fallback
-		return url;
-	}
-
 	private function publish(mode:String, name:String, cam:Camera, mic:Microphone, f:Function):void {
 		if (nc == null || !nc.connected) {
-			var url:String = getUrl();
+			var url:String = params.url;  //TODO fallback
 			debug("NetConnection is not connected", url);
 			nc = new NetConnection();
 			nc.addEventListener(NetStatusEvent.NET_STATUS, function onConnectionStatus(e:NetStatusEvent):void {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-server/src/site/xdoc/Clustering.xml
----------------------------------------------------------------------
diff --git a/openmeetings-server/src/site/xdoc/Clustering.xml b/openmeetings-server/src/site/xdoc/Clustering.xml
index a1ccc27..9d073d1 100644
--- a/openmeetings-server/src/site/xdoc/Clustering.xml
+++ b/openmeetings-server/src/site/xdoc/Clustering.xml
@@ -80,7 +80,7 @@
 			</ul> 
 		</section>
 		<section name="OM nodes configuration">
-			<p>In the file <tt>/opt/red5/webapps/openmeetings/WEB-INF/classes/openmeetings-applicationContext.xml</tt>:</p>
+			<p>In the file <tt>/opt/red5/webapps/openmeetings/WEB-INF/classes/applicationContext.xml</tt>:</p>
 			<ul>
 				<li>
 					For each node uncomment line:

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-server/src/site/xdoc/voip-sip-integration.xml
----------------------------------------------------------------------
diff --git a/openmeetings-server/src/site/xdoc/voip-sip-integration.xml b/openmeetings-server/src/site/xdoc/voip-sip-integration.xml
index 9369ee7..72cf707 100644
--- a/openmeetings-server/src/site/xdoc/voip-sip-integration.xml
+++ b/openmeetings-server/src/site/xdoc/voip-sip-integration.xml
@@ -61,9 +61,12 @@
                 <a href="red5sip-integration_3.1.html">
                 Instruction how-to set up OpenMeetings SIP-Transport integration for Openmeetings 3.1+
                 </a>.<br/>
+				<a href="red5sip-integration_4.0.html">
+				Instruction how-to set up OpenMeetings SIP-Transport integration for Openmeetings 4.0+
+				</a>.<br/>
 			</p>
 		</section>
 
 	</body>
 
-</document>
\ No newline at end of file
+</document>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index b40c9e2..0f361dd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -99,8 +99,7 @@ import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.mapper.info.PageComponentInfo;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
-import org.apache.wicket.request.resource.JavaScriptResourceReference;
-import org.apache.wicket.resource.DynamicJQueryResourceReference;
+import org.apache.wicket.resource.JQueryResourceReference;
 import org.apache.wicket.util.collections.ConcurrentHashSet;
 import org.apache.wicket.validation.validator.UrlValidator;
 import org.slf4j.Logger;
@@ -138,8 +137,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 		//chain of Resource Loaders, if not found it will search in Wicket's internal
 		//Resource Loader for a the property key
 		getResourceSettings().getStringResourceLoaders().add(0, new LabelResourceLoader());
-		//FIXME TODO v3 on the way
-		getJavaScriptLibrarySettings().setJQueryReference(new JavaScriptResourceReference(DynamicJQueryResourceReference.class, DynamicJQueryResourceReference.VERSION_2));
+		getJavaScriptLibrarySettings().setJQueryReference(JQueryResourceReference.getV3());
 
 		super.init();
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
index 8fa58ff..9ec4dea 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
@@ -34,16 +34,20 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.IUpdatable;
 import org.apache.openmeetings.web.common.MainPanel;
+import org.apache.openmeetings.web.common.OmAjaxClientInfoBehavior;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.SwfPanel;
+import org.apache.openmeetings.web.room.VideoSettings;
 import org.apache.openmeetings.web.user.record.VideoInfo;
 import org.apache.openmeetings.web.user.record.VideoPlayer;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.markup.head.CssHeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.panel.EmptyPanel;
+import org.apache.wicket.protocol.http.request.WebClientInfo;
 import org.apache.wicket.request.IRequestParameters;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.util.string.StringValue;
@@ -137,9 +141,25 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 			}
 		}
 		StringValue swf = p.get(SWF);
-		if (!swf.isEmpty() && (SWF_TYPE_NETWORK.equals(swf.toString()) || SWF_TYPE_SETTINGS.equals(swf.toString()))) {
-			replace(new SwfPanel(PANEL_MAIN, p));
-			error = false;
+		if (!swf.isEmpty()) {
+			if (SWF_TYPE_NETWORK.equals(swf.toString())) {
+				replace(new SwfPanel(PANEL_MAIN, p));
+				error = false;
+			}
+			if (SWF_TYPE_SETTINGS.equals(swf.toString())) {
+				replace(new VideoSettings(PANEL_MAIN).add(new OmAjaxClientInfoBehavior() {
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					protected void onClientInfo(AjaxRequestTarget target, WebClientInfo info) {
+						super.onClientInfo(target, info);
+						target.appendJavaScript(
+								VideoSettings.getInitScript((ExtendedClientProperties)info.getProperties(), "hibernate", "networktest")
+								.append("VideoSettings.open();"));
+					}
+				}));
+				error = false;
+			}
 		}
 		add(recContainer.add(vi.setShowShare(false).setOutputMarkupPlaceholderTag(true),
 				vp.setOutputMarkupPlaceholderTag(true)), new InvitationPasswordDialog("i-pass", this));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index b05150f..c4d9728 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -27,8 +27,6 @@ import static org.apache.openmeetings.web.app.Application.getRoomClients;
 import static org.apache.openmeetings.web.app.WebSession.getDateFormat;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.util.Calendar;
 import java.util.List;
 import java.util.Map.Entry;
@@ -36,7 +34,6 @@ import java.util.Set;
 import java.util.UUID;
 
 import org.apache.directory.api.util.Strings;
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
 import org.apache.openmeetings.db.dao.log.ConferenceLogDao;
@@ -65,6 +62,7 @@ import org.apache.openmeetings.web.room.activities.Activity;
 import org.apache.openmeetings.web.room.menu.RoomMenuPanel;
 import org.apache.openmeetings.web.room.sidebar.RoomSidebar;
 import org.apache.openmeetings.web.room.wb.WbPanel;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
@@ -77,14 +75,12 @@ import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.protocol.http.ClientProperties;
 import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
-import com.github.openjson.JSONObject;
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
 import com.googlecode.wicket.jquery.ui.interaction.droppable.Droppable;
@@ -113,30 +109,13 @@ public class RoomPanel extends BasePanel {
 		@Override
 		protected void respond(AjaxRequestTarget target) {
 			target.appendJavaScript("setRoomSizes();");
+			ExtendedClientProperties cp = WebSession.get().getExtendedProperties();
 			getBean(ConferenceLogDao.class).add(
 					ConferenceLog.Type.roomEnter
 					, getUserId(), "0", r.getId()
-					, WebSession.get().getClientInfo().getProperties().getRemoteAddress()
+					, cp.getRemoteAddress()
 					, "" + r.getId());
-			//TODO SID etc
-			try {
-				URL url = new URL(WebSession.get().getExtendedProperties().getCodebase());
-				String path = url.getPath();
-				path = path.substring(1, path.indexOf('/', 2) + 1);
-				ClientProperties cp = WebSession.get().getClientInfo().getProperties();
-				target.appendJavaScript(String.format("VideoSettings.init(%s);", new JSONObject(getBean(ScopeApplicationAdapter.class).getFlashSettings().toString())
-						.put("uid", getClient().getUid())
-						.put("audioOnly", r.isAudioOnly())
-						.put("SID", WebSession.getSid())
-						.put("interview", Room.Type.interview == r.getType())
-						.put("host", url.getHost())
-						.put("app", path + r.getId())
-						.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct")
-						.toString()
-						));
-			} catch (NullPointerException|MalformedURLException e) {
-				log.error("Error while constructing room parameters", e);
-			}
+			target.appendJavaScript(VideoSettings.getInitScript(cp, "" + r.getId(), getClient().getUid()));
 			WebSocketHelper.sendRoom(new RoomMessage(r.getId(), getUserId(), RoomMessage.Type.roomEnter));
 			getMainPanel().getChat().roomEnter(r, target);
 			if (r.isFilesOpened()) {
@@ -616,10 +595,9 @@ public class RoomPanel extends BasePanel {
 
 	public boolean screenShareAllowed() {
 		Room r = getRoom();
-		org.apache.openmeetings.db.entity.room.Client rcl = RoomBroadcaster.getClient(getMainPanel().getClient().getUid());
 		return Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing)
 				&& r.isAllowRecording() && getClient().hasRight(Right.share)
-				&& getSharingUser() == null && rcl != null && rcl.getUserId() != null;
+				&& getSharingUser() == null;
 	}
 
 	public RoomSidebar getSidebar() {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html
new file mode 100644
index 0000000..bd931f7
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.html
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+      http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<wicket:panel>
+	<div id="video-settings" wicket:message="title:51, data-btn-save:144, data-btn-cancel:25" style="display:none;">
+		<div class="title"><wicket:message key="758"/></div>
+		<div class="sett-container">
+			<div class="opt-block">
+				<div class="sett-row">
+					<div><wicket:message key="52"/></div>
+					<div>
+						<select class="cam">
+							<option value="-1"><wicket:message key="159"/></option>
+						</select>
+					</div>
+				</div>
+				<div class="sett-row">
+					<div><wicket:message key="53"/></div>
+					<div>
+						<select class="mic">
+							<option value="-1"><wicket:message key="159"/></option>
+						</select>
+					</div>
+				</div>
+				<div class="sett-row">
+					<div class="clear">
+						<wicket:message key="1429"/>
+						<span class="warn ui-state-highlight" wicket:message="title:1430">
+							<span class="ui-icon ui-icon-alert"></span>
+						</span>
+					</div>
+					<div>
+						<select class="cam-resolution">
+							<option value="1" data-width="40" data-height="30">40x30 [4:3 (~6 KByte/sec)]</option>
+							<option value="2" data-width="80" data-height="60">80x60 [4:3 (~12 KByte/sec)]</option>
+							<option value="3" data-width="120" data-height="90" selected="selected">120x90 [4:3 (~20 KByte/sec)]</option>
+							<option value="4" data-width="160" data-height="120">160x120 [QQVGA 4:3 (~36 KByte/sec)]</option>
+							<option value="5" data-width="240" data-height="180">240x180 [4:3 (~40 KByte/sec)]</option>
+							<option value="6" data-width="320" data-height="240">320x240 [HVGA 4:3 (~56 KByte/sec)]</option>
+							<option value="7" data-width="480" data-height="360">480x360 [4:3  (~60 KByte/sec)]</option>
+							<option value="8" data-width="640" data-height="480">640x480 [4:3 (~68 KByte/sec)]</option>
+							<option value="9" data-width="1024" data-height="768">1024x768 [XGA 4:3]</option>
+							<option value="10" data-width="256" data-height="150">256x150 [16:9]</option>
+							<option value="11" data-width="432" data-height="240">432x240 [WQVGA 9:5]</option>
+							<option value="12" data-width="480" data-height="234">480x234 [pseudo 16:9]</option>
+							<option value="13" data-width="512" data-height="300">512x300 [16:9]</option>
+							<option value="14" data-width="640" data-height="360">640x360 [nHD 16:9]</option>
+							<option value="15" data-width="1024" data-height="600">1024x600 [16:9]</option>
+						</select>
+					</div>
+				</div>
+				<div class="sett-row right">
+					<div><button class="rec-start"><wicket:message key="775"/></button></div>
+				</div>
+			</div>
+			<div class="vid-block">
+				<div class="video-conainer"></div>
+				<div class="level-meter"></div>
+				<div class="sett-row right">
+					<div><button class="play"><wicket:message key="764"/></button></div>
+				</div>
+			</div>
+		</div>
+		<div>
+			<span style="padding: 5px;">
+				<span class="ui-icon ui-icon-info"></span>
+			</span>
+			<wicket:message key="765"/>
+		</div>
+	</div>
+</wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
new file mode 100644
index 0000000..98319fc
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_FPS;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_NATIVE_SSL;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_PORT;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SECURE;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SSL_PORT;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_VIDEO_CODEC;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.web.app.Application.getBean;
+
+import java.net.URL;
+
+import org.apache.directory.api.util.Strings;
+import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.web.app.WebSession;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.head.PriorityHeaderItem;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+
+import com.github.openjson.JSONObject;
+
+public class VideoSettings extends Panel {
+	private final static long serialVersionUID = 1L;
+	private final static Logger log = Red5LoggerFactory.getLogger(VideoSettings.class, webAppRootKey);
+	private final static ResourceReference SETTINGS_JS_REFERENCE = new JavaScriptResourceReference(VideoSettings.class, "settings.js");
+	private final static String URL = "url";
+	private final static String FALLBACK = "fallback";
+
+	public VideoSettings(String id) {
+		super(id);
+	}
+
+	@Override
+	public void renderHead(IHeaderResponse response) {
+		super.renderHead(response);
+		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(SETTINGS_JS_REFERENCE)));
+	}
+
+	private static String getUri(String protocol, String host, Object port, String app) {
+		return String.format("%s://%s:%s/%s", protocol, host, port, app);
+	}
+
+	public static StringBuilder getInitScript(ExtendedClientProperties cp, String scope, String uid) {
+		JSONObject gs = getBean(ScopeApplicationAdapter.class).getFlashSettings();
+		JSONObject s = new JSONObject()
+				.put(FLASH_VIDEO_CODEC, gs.get(FLASH_VIDEO_CODEC))
+				.put(FLASH_FPS, gs.get(FLASH_FPS))
+				.put("SID", WebSession.getSid())
+				.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct");
+		if (!Strings.isEmpty(uid)) {
+			s.put("uid", uid);
+		}
+		try {
+			URL url = new URL(cp.getCodebase());
+			String path = url.getPath();
+			path = path.substring(1, path.indexOf('/', 2) + 1) + scope;
+			if (gs.getBoolean(FLASH_SECURE)) {
+				s.put(FLASH_NATIVE_SSL, gs.get(FLASH_NATIVE_SSL));
+				s.put(URL, getUri("rtmps", url.getHost(), gs.getString(FLASH_SSL_PORT), path));
+				s.put(FALLBACK, getUri("rtmps", url.getHost(), url.getPort(), path));
+			} else {
+				s.put(URL, getUri("rtmp", url.getHost(), gs.getString(FLASH_PORT), path));
+				s.put(FALLBACK, getUri("rtmpt", url.getHost(), url.getPort(), path));
+			}
+		} catch (Exception e) {
+			log.error("Error while constructing video settings parameters", e);
+		}
+		return new StringBuilder("VideoSettings.init(").append(s.toString()).append(");");
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index 1e2c563..989aa20 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -16,19 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-function initVideo(el, id, options) {
-	var type = 'application/x-shockwave-flash';
-	var src = 'public/main.swf?cache' + new Date().getTime();
-	var o = $('<object>').attr('id', id).attr('type', type).attr('data', src).attr('width', options.width).attr('height', options.height);
-	o.append($('<param>').attr('name', 'quality').attr('value', 'best'))
-		.append($('<param>').attr('name', 'wmode').attr('value', options.wmode))
-		.append($('<param>').attr('name', 'allowscriptaccess').attr('value', 'sameDomain'))
-		.append($('<param>').attr('name', 'allowfullscreen').attr('value', 'false'))
-		.append($('<param>').attr('name', 'flashvars').attr('value', $.param(options)));
-	el.append(o);
-	return o;
-}
-
 function setRoomSizes() {
 	var sb = $(".room.sidebar.left")
 		, w = $(window).width() - sb.width() - 5
@@ -92,156 +79,6 @@ function startPrivateChat(el) {
 	Chat.open();
 	$('#chatMessage .wysiwyg-editor').click();
 }
-var VideoSettings = (function() {
-	var self = {}, vs, lm, swf, s, cam, mic, res,
-		vidScroll, recBtn, playBtn, inited = false, recAllowed = false;
-	function _load() {
-		s = {};
-		try {
-			s = JSON.parse(localStorage.getItem('openmeetings')) || s;
-		} catch (e) {}
-		if (!s.video) {
-			s.video = {};
-		}
-	}
-	function _save() {
-		localStorage.setItem('openmeetings', JSON.stringify(s));
-	}
-	function _init(options) {
-		vs = $('#video-settings');
-		lm = vs.find('.level-meter');
-		cam = vs.find('select.cam');
-		mic = vs.find('select.mic');
-		res = vs.find('select.cam-resolution');
-		vidScroll = vs.find('.vid-block .video-conainer');
-		recBtn = vs.find('.rec-start').click(function() {
-			recBtn.prop('disabled', true).button('refresh'); //TODO disable drop-downs
-			swf.startRec();
-		});
-		playBtn = vs.find('.play').click(function() {
-			swf.play();
-		});
-		vs.dialog({
-			classes: {
-				'ui-dialog': 'ui-corner-all video'
-			}
-			, width: 640
-			, autoOpen: false
-			, buttons: [
-				{
-					text: vs.data('btn-save')
-					, icons: {
-						primary: "ui-icon-disk"
-					}
-					, click: function() {
-						_save();
-						vs.dialog("close");
-					}
-				}
-				, {
-					text: vs.data('btn-cancel')
-					, click: function() {
-						vs.dialog("close");
-					}
-				}
-			]
-		});
-		lm.progressbar({ value: 0 });
-		options.width = 300;
-		options.height = 200;
-		swf = initVideo(vidScroll, 'video-settings-swf', options)[0];
-		vs.find('input, button').prop('disabled', true);
-		vs.find('button').button();
-		var rr = vs.find('.cam-resolution').parent('.sett-row');
-		if (!!options.interview) {
-			rr.show();
-		} else {
-			rr.hide();
-		}
-		_load();
-	}
-	function _updateRec() {
-		recBtn.prop('disabled', !recAllowed && (s.video.cam > -1 || s.video.mic > -1)).button('refresh');
-	}
-	function _readValues() {
-		s.video.cam = 1 * cam.val();
-		s.video.mic = 1 * mic.val();
-		var o = res.find('option:selected').data();
-		s.video.width = o.width;
-		s.video.height = o.height;
-		$(swf).attr('width', Math.max(300, s.video.width)).attr('height', Math.max(200, s.video.height));
-		vidScroll.scrollLeft(Math.max(0, s.video.width / 2 - 150))
-			.scrollTop(Math.max(0, s.video.height / 2 - 110));
-		_updateRec();
-	}
-	
-	function _allowRec(allow) {
-		recAllowed = allow;
-		_updateRec();
-	}
-	function _allowPlay() {
-		_updateRec();
-		playBtn.prop('disabled', false).button('refresh');
-	}
-	function _micActivity(level) {
-		console.log("activity: ", level)
-		lm.progressbar("value", Math.max(0, level));
-	}
-	function _initSwf() {
-		if (!inited) {
-			var obj = swf.getDevices();
-			for (var i = 0; i < obj.cams.length; ++i) {
-				var o = $('<option></option>').attr('value', i).text(obj.cams[i]);
-				if (i == s.video.cam) {
-					o.prop('selected', true);
-				}
-				cam.append(o);
-			}
-			cam.prop('disabled', false).change(function() {
-				_readValues();
-				swf.camChanged(s.video.cam);
-			});
-			for (var i = 0; i < obj.mics.length; ++i) {
-				var o = $('<option></option>').attr('value', i).text(obj.mics[i]);
-				if (i == s.video.mic) {
-					o.prop('selected', true);
-				}
-				mic.append(o);
-			}
-			mic.prop('disabled', false).change(function() {
-				_readValues();
-				swf.micChanged(s.video.mic);
-			});
-			res.change(function() {
-				_readValues();
-				swf.resChanged(s.video.width, s.video.height);
-			});
-			res.find('option').each(function(idx) {
-				var o = $(this).data();
-				if (o.width == s.video.width && o.height == s.video.height) {
-					$(this).prop('selected', true);
-					return false;
-				}
-			});
-		}
-		_readValues();
-		swf.init(s.video.cam, s.video.mic, s.video.width, s.video.height);
-	}
-	function _open() {
-		recAllowed = false;
-		vs.dialog('open');
-	}
-	return {
-		init: _init
-		, initSwf: _initSwf
-		, open: _open
-		, allowRec: _allowRec
-		, allowPlay: _allowPlay
-		, micActivity: _micActivity
-		, close: function() { vs.dialog('close'); }
-	};
-})();
-
 /***** functions required by SIP   ******/
 function sipBtnClick() {
 	var txt = $('.sip-number');

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
new file mode 100644
index 0000000..9c96224
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
@@ -0,0 +1,179 @@
+/**
+ * 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.
+ */
+function initVideo(el, id, options) {
+	var type = 'application/x-shockwave-flash';
+	var src = 'public/main.swf?cache' + new Date().getTime();
+	var o = $('<object>').attr('id', id).attr('type', type).attr('data', src).attr('width', options.width).attr('height', options.height);
+	o.append($('<param>').attr('name', 'quality').attr('value', 'best'))
+		.append($('<param>').attr('name', 'wmode').attr('value', options.wmode))
+		.append($('<param>').attr('name', 'allowscriptaccess').attr('value', 'sameDomain'))
+		.append($('<param>').attr('name', 'allowfullscreen').attr('value', 'false'))
+		.append($('<param>').attr('name', 'flashvars').attr('value', $.param(options)));
+	el.append(o);
+	return o;
+}
+var VideoSettings = (function() {
+	var self = {}, vs, lm, swf, s, cam, mic, res,
+		vidScroll, recBtn, playBtn, inited = false, recAllowed = false;
+	function _load() {
+		s = {};
+		try {
+			s = JSON.parse(localStorage.getItem('openmeetings')) || s;
+		} catch (e) {}
+		if (!s.video) {
+			s.video = {};
+		}
+	}
+	function _save() {
+		localStorage.setItem('openmeetings', JSON.stringify(s));
+	}
+	function _init(options) {
+		vs = $('#video-settings');
+		lm = vs.find('.level-meter');
+		cam = vs.find('select.cam');
+		mic = vs.find('select.mic');
+		res = vs.find('select.cam-resolution');
+		vidScroll = vs.find('.vid-block .video-conainer');
+		recBtn = vs.find('.rec-start').click(function() {
+			recBtn.prop('disabled', true).button('refresh'); //TODO disable drop-downs
+			swf.startRec();
+		});
+		playBtn = vs.find('.play').click(function() {
+			swf.play();
+		});
+		vs.dialog({
+			classes: {
+				'ui-dialog': 'ui-corner-all video'
+			}
+			, width: 640
+			, autoOpen: false
+			, buttons: [
+				{
+					text: vs.data('btn-save')
+					, icons: {
+						primary: "ui-icon-disk"
+					}
+					, click: function() {
+						_save();
+						vs.dialog("close");
+					}
+				}
+				, {
+					text: vs.data('btn-cancel')
+					, click: function() {
+						vs.dialog("close");
+					}
+				}
+			]
+		});
+		lm.progressbar({ value: 0 });
+		options.width = 300;
+		options.height = 200;
+		swf = initVideo(vidScroll, 'video-settings-swf', options)[0];
+		vs.find('input, button').prop('disabled', true);
+		vs.find('button').button();
+		var rr = vs.find('.cam-resolution').parent('.sett-row');
+		if (!!options.interview) {
+			rr.show();
+		} else {
+			rr.hide();
+		}
+		_load();
+	}
+	function _updateRec() {
+		recBtn.prop('disabled', !recAllowed && (s.video.cam > -1 || s.video.mic > -1)).button('refresh');
+	}
+	function _readValues() {
+		s.video.cam = 1 * cam.val();
+		s.video.mic = 1 * mic.val();
+		var o = res.find('option:selected').data();
+		s.video.width = o.width;
+		s.video.height = o.height;
+		$(swf).attr('width', Math.max(300, s.video.width)).attr('height', Math.max(200, s.video.height));
+		vidScroll.scrollLeft(Math.max(0, s.video.width / 2 - 150))
+			.scrollTop(Math.max(0, s.video.height / 2 - 110));
+		_updateRec();
+	}
+	
+	function _allowRec(allow) {
+		recAllowed = allow;
+		_updateRec();
+	}
+	function _allowPlay() {
+		_updateRec();
+		playBtn.prop('disabled', false).button('refresh');
+	}
+	function _micActivity(level) {
+		console.log("activity: ", level)
+		lm.progressbar("value", Math.max(0, level));
+	}
+	function _initSwf() {
+		if (!inited) {
+			var obj = swf.getDevices();
+			for (var i = 0; i < obj.cams.length; ++i) {
+				var o = $('<option></option>').attr('value', i).text(obj.cams[i]);
+				if (i == s.video.cam) {
+					o.prop('selected', true);
+				}
+				cam.append(o);
+			}
+			cam.prop('disabled', false).change(function() {
+				_readValues();
+				swf.camChanged(s.video.cam);
+			});
+			for (var i = 0; i < obj.mics.length; ++i) {
+				var o = $('<option></option>').attr('value', i).text(obj.mics[i]);
+				if (i == s.video.mic) {
+					o.prop('selected', true);
+				}
+				mic.append(o);
+			}
+			mic.prop('disabled', false).change(function() {
+				_readValues();
+				swf.micChanged(s.video.mic);
+			});
+			res.change(function() {
+				_readValues();
+				swf.resChanged(s.video.width, s.video.height);
+			});
+			res.find('option').each(function(idx) {
+				var o = $(this).data();
+				if (o.width == s.video.width && o.height == s.video.height) {
+					$(this).prop('selected', true);
+					return false;
+				}
+			});
+		}
+		_readValues();
+		swf.init(s.video.cam, s.video.mic, s.video.width, s.video.height);
+	}
+	function _open() {
+		recAllowed = false;
+		vs.dialog('open');
+	}
+	return {
+		init: _init
+		, initSwf: _initSwf
+		, open: _open
+		, allowRec: _allowRec
+		, allowPlay: _allowPlay
+		, micActivity: _micActivity
+		, close: function() { vs.dialog('close'); }
+	};
+})();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
index 5809dcd..e92ae35 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
@@ -40,71 +40,6 @@
 	<form wicket:id="form"><div wicket:id="confirm-trash"></div></form>
 	<div wicket:id="upload"></div>
 	<div wicket:id="confirm-kick" />
-	<div id="video-settings" wicket:message="title:51, data-btn-save:144, data-btn-cancel:25" style="display:none;">
-		<div class="title"><wicket:message key="758"/></div>
-		<div class="sett-container">
-			<div class="opt-block">
-				<div class="sett-row">
-					<div><wicket:message key="52"/></div>
-					<div>
-						<select class="cam">
-							<option value="-1"><wicket:message key="159"/></option>
-						</select>
-					</div>
-				</div>
-				<div class="sett-row">
-					<div><wicket:message key="53"/></div>
-					<div>
-						<select class="mic">
-							<option value="-1"><wicket:message key="159"/></option>
-						</select>
-					</div>
-				</div>
-				<div class="sett-row">
-					<div class="clear">
-						<wicket:message key="1429"/>
-						<span class="warn ui-state-highlight" wicket:message="title:1430">
-							<span class="ui-icon ui-icon-alert"></span>
-						</span>
-					</div>
-					<div>
-						<select class="cam-resolution">
-							<option value="1" data-width="40" data-height="30">40x30 [4:3 (~6 KByte/sec)]</option>
-							<option value="2" data-width="80" data-height="60">80x60 [4:3 (~12 KByte/sec)]</option>
-							<option value="3" data-width="120" data-height="90" selected="selected">120x90 [4:3 (~20 KByte/sec)]</option>
-							<option value="4" data-width="160" data-height="120">160x120 [QQVGA 4:3 (~36 KByte/sec)]</option>
-							<option value="5" data-width="240" data-height="180">240x180 [4:3 (~40 KByte/sec)]</option>
-							<option value="6" data-width="320" data-height="240">320x240 [HVGA 4:3 (~56 KByte/sec)]</option>
-							<option value="7" data-width="480" data-height="360">480x360 [4:3  (~60 KByte/sec)]</option>
-							<option value="8" data-width="640" data-height="480">640x480 [4:3 (~68 KByte/sec)]</option>
-							<option value="9" data-width="1024" data-height="768">1024x768 [XGA 4:3]</option>
-							<option value="10" data-width="256" data-height="150">256x150 [16:9]</option>
-							<option value="11" data-width="432" data-height="240">432x240 [WQVGA 9:5]</option>
-							<option value="12" data-width="480" data-height="234">480x234 [pseudo 16:9]</option>
-							<option value="13" data-width="512" data-height="300">512x300 [16:9]</option>
-							<option value="14" data-width="640" data-height="360">640x360 [nHD 16:9]</option>
-							<option value="15" data-width="1024" data-height="600">1024x600 [16:9]</option>
-						</select>
-					</div>
-				</div>
-				<div class="sett-row right">
-					<div><button class="rec-start"><wicket:message key="775"/></button></div>
-				</div>
-			</div>
-			<div class="vid-block">
-				<div class="video-conainer"></div>
-				<div class="level-meter"></div>
-				<div class="sett-row right">
-					<div><button class="play"><wicket:message key="764"/></button></div>
-				</div>
-			</div>
-		</div>
-		<div>
-			<span style="padding: 5px;">
-				<span class="ui-icon ui-icon-info"></span>
-			</span>
-			<wicket:message key="765"/>
-		</div>
-	</div>
+	<div wicket:id="settings" />
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index b09e688..ffa6ba1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -34,12 +34,13 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.room.RoomBroadcaster;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
+import org.apache.openmeetings.web.room.VideoSettings;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -89,6 +90,7 @@ public class RoomSidebar extends Panel {
 	private boolean avInited = false;
 	private int selectedIdx = 0;
 	private Client kickedClient;
+	private VideoSettings settings = new VideoSettings("settings");
 	private final ListView<Client> users = new ListView<Client>("user", new ArrayList<Client>()) {
 		private static final long serialVersionUID = 1L;
 
@@ -314,7 +316,7 @@ public class RoomSidebar extends Panel {
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
-		add(addFolder);
+		add(addFolder, settings);
 		add(toggleRight, toggleActivity, roomAction, avSettings);
 		add(confirmKick = new ConfirmableAjaxBorder("confirm-kick", getString("603"), getString("605")) {
 			private static final long serialVersionUID = 1L;


[24/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] hash?swf=settings is fixed, code clean-up

Posted by so...@apache.org.
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
new file mode 100644
index 0000000..a4ade15
--- /dev/null
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:tx="http://www.springframework.org/schema/tx"
+	xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+	xmlns:jaxws="http://cxf.apache.org/jaxws"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xsi:schemaLocation="
+		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
+		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
+		http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
+		http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"
+		>
+	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
+		<property name="persistenceUnitName" value="openmeetings" />
+	</bean>
+	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+		<property name="entityManagerFactory" ref="entityManagerFactory" />
+	</bean>
+	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
+
+	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
+	<context:annotation-config />
+	<context:component-scan base-package="org.apache.openmeetings" />
+
+	<!-- New Class for the Streaming Handlers -->
+	<bean id="web.handler" class="org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter" />
+
+	<!-- Session configuration start -->
+
+	<bean id="openmeetings.SessionManager" class="org.apache.openmeetings.core.session.SessionManager">
+		<property name="cache">
+			<!-- Memory based session cache by default -->
+			<ref bean="openmeetings.HashMapStore" />
+			<!-- The following section should be used in clustering mode
+			<ref bean="openmeetings.DatabaseStore" />
+			-->
+		</property>
+	</bean>
+
+	<!-- Singleton for memory based cache -->
+	<bean id="openmeetings.HashMapStore" scope="singleton" class="org.apache.openmeetings.core.session.store.HashMapStore" />
+	<!-- Database cache -->
+	<bean id="openmeetings.DatabaseStore" class="org.apache.openmeetings.core.session.store.DatabaseStore" />
+	
+	<bean id="whiteboardCache" scope="singleton" class="org.apache.openmeetings.core.data.whiteboard.WhiteboardCache" />
+
+	<!-- Cluster related config start -->
+	<bean id="openmeetings.ServerUtil" scope="singleton" class="org.apache.openmeetings.core.session.ServerUtil">
+		<!-- Need to be uncommented and set to the real ID if in cluster mode
+		<property name="serverId" value="1" />
+		-->
+	</bean>
+
+	<!-- Start of Services -->
+	<bean id="xmlcrm.service" class="org.apache.openmeetings.core.remote.MainService" />
+	<bean id="userservice.service" class="org.apache.openmeetings.core.remote.UserService" />
+	<bean id="fileservice.service" class="org.apache.openmeetings.core.remote.ConferenceLibrary" />
+	<bean id="openmeetings.FileProcessor" class="org.apache.openmeetings.core.data.file.FileProcessor" />
+	<bean id="openmeetings.FlvExplorerConverter" class="org.apache.openmeetings.core.converter.FlvExplorerConverter" />
+	<bean id="recordingservice.service" class="org.apache.openmeetings.core.remote.RecordingService" />
+	<bean id="mobile.service" class="org.apache.openmeetings.core.remote.MobileService" />
+	<bean id="openmeetings.RecordingConverterTask" class="org.apache.openmeetings.core.data.record.converter.RecordingConverterTask" />
+	<bean id="openmeetings.InterviewConverterTask" class="org.apache.openmeetings.core.data.record.converter.InterviewConverterTask" />
+	<bean id="openmeetings.InterviewConverter" class="org.apache.openmeetings.core.converter.InterviewConverter" />
+	<bean id="openmeetings.RecordingConverter" class="org.apache.openmeetings.core.converter.RecordingConverter" />
+	<bean id="openmeetings.SlaveHTTPConnectionManager" class="org.apache.openmeetings.webservice.cluster.SlaveHTTPConnectionManager" />
+
+	 <!--	1800000 == 30 min
+	 		3600000 == 1 hour
+	 		5000	== 5 sec
+	 		300000	== 5 min
+	 		900000	== 15 min
+	 -->
+	<bean id="cleanupJob" class="org.apache.openmeetings.service.quartz.scheduler.CleanupJob"
+			p:sessionTimeout="1800000" p:testSetupTimeout="3600000" p:roomFilesTtl="3600000" />
+	<bean id="cleanSessionsJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="cleanupJob" p:targetMethod="cleanSessions" p:concurrent="false" />
+	<bean id="triggerCleanSessions" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="cleanSessionsJobDetails" p:startDelay="5000" p:repeatInterval="300000" />
+	<bean id="cleanTestSetupJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="cleanupJob" p:targetMethod="cleanTestSetup" p:concurrent="false" />
+	<bean id="triggerCleanTestSetup" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="cleanTestSetupJobDetail" p:startDelay="1800000" p:repeatInterval="1800000" />
+	<bean id="cleanRoomFilesJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="cleanupJob" p:targetMethod="cleanRoomFiles" p:concurrent="false" />
+	<bean id="triggerCleanRoomFiles" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="cleanRoomFilesJobDetail" p:startDelay="10000" p:repeatInterval="1800000" /> <!-- p:startDelay="1800000" -->
+	<bean id="cleanExpiredRecJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="cleanupJob" p:targetMethod="cleanExpiredRecordings" p:concurrent="false" />
+	<bean id="triggerCleanExpiredRec" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="cleanExpiredRecJobDetails" p:startDelay="5000" p:repeatInterval="3600000" />
+
+	<bean id="reminderJob" class="org.apache.openmeetings.service.quartz.scheduler.ReminderJob"/>
+	<bean id="meetingReminderJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="reminderJob" p:targetMethod="remindMeetings" p:concurrent="false" />
+	<bean id="triggerMeetingReminder" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="meetingReminderJobDetail" p:startDelay="5000" p:repeatInterval="100000"/>
+	<bean id="expiringRecordingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="reminderJob" p:targetMethod="remindExpiringRecordings" p:concurrent="false" />
+	<bean id="triggerExpiringRecording" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="expiringRecordingJobDetail" p:startDelay="5000" p:repeatInterval="3600000"/>
+
+	<!-- Mail related jobs -->
+	<bean id="mailHandler" class="org.apache.openmeetings.core.mail.MailHandler" />
+	<bean id="resetSendingMailStatus" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="mailHandler" p:targetMethod="resetSendingStatus" p:concurrent="false" />
+	<bean id="triggerResetSendingMailStatus" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="resetSendingMailStatus" p:startDelay="60000" p:repeatInterval="900000" />
+	<bean id="sendMails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+			p:targetObject-ref="mailHandler" p:targetMethod="sendMails" p:concurrent="false" />
+	<bean id="triggerSendMails" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+			p:jobDetail-ref="sendMails" p:startDelay="60000" p:repeatInterval="60000" />
+	
+	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
+		<property name="triggers">
+			<list>
+				<ref bean="triggerCleanSessions" />
+				<ref bean="triggerCleanTestSetup" />
+				<ref bean="triggerCleanRoomFiles" />
+				<ref bean="triggerCleanExpiredRec" />
+				<ref bean="triggerMeetingReminder" />
+				<ref bean="triggerExpiringRecording" />
+				<ref bean="triggerResetSendingMailStatus" />
+				<ref bean="triggerSendMails" />
+			</list>
+		</property>
+	</bean>
+	<!-- End of Services -->
+
+	<!-- Interface Transactional -->
+	<bean id="roommanagement" class="org.apache.openmeetings.core.data.conference.RoomManager" />
+	<bean id="roomDao" class="org.apache.openmeetings.db.dao.room.RoomDao"/>
+	<bean id="sipDao" class="org.apache.openmeetings.db.dao.room.SipDao">
+	<!--  Should be uncommented and updated with real values for Asterisk
+		<constructor-arg><value>127.0.0.1</value></constructor-arg>
+		<constructor-arg><value>5038</value></constructor-arg>
+		<constructor-arg><value>openmeetings</value></constructor-arg>
+		<constructor-arg><value>12345</value></constructor-arg>
+		<constructor-arg><value>10000</value></constructor-arg>
+	 -->
+	</bean>
+	<bean id="invitationDao" class="org.apache.openmeetings.db.dao.room.InvitationDao" />
+	<bean id="groupDao" class="org.apache.openmeetings.db.dao.user.GroupDao" />
+	<bean id="groupUserDao" class="org.apache.openmeetings.db.dao.user.GroupUserDao" />
+	<bean id="errorManagement" class="org.apache.openmeetings.db.dao.basic.ErrorDao" />
+	<bean id="navimanagement" class="org.apache.openmeetings.db.dao.basic.NavigationDao" />
+	<bean id="pollManagement" class="org.apache.openmeetings.db.dao.room.PollDao" />
+	<bean id="labelDao" class="org.apache.openmeetings.db.dao.label.LabelDao" />
+	<bean id="configurationDaoImpl" class="org.apache.openmeetings.db.dao.basic.ConfigurationDao" />
+	<bean id="appointmentDao" class="org.apache.openmeetings.db.dao.calendar.AppointmentDao" />
+	<bean id="appointmentLogic" class="org.apache.openmeetings.service.calendar.AppointmentLogic" />
+	<bean id="sessionManagement" class="org.apache.openmeetings.db.dao.server.SessiondataDao" />
+	<bean id="userManagement" class="org.apache.openmeetings.service.user.UserManager" />
+	<bean id="roomModeratorDao" class="org.apache.openmeetings.db.dao.room.RoomModeratorDao" />
+	<bean id="roomGroupDao" class="org.apache.openmeetings.db.dao.room.RoomGroupDao"/>
+	<bean id="conferenceLogDao" class="org.apache.openmeetings.db.dao.log.ConferenceLogDao" />
+	<bean id="emailManagement" class="org.apache.openmeetings.service.mail.EmailManager" />
+	<bean id="fileItemLogDao" class="org.apache.openmeetings.db.dao.file.FileItemLogDao" />
+	<bean id="fileExplorerItemDao" class="org.apache.openmeetings.db.dao.file.FileExplorerItemDao" />
+	<bean id="recordingDao" class="org.apache.openmeetings.db.dao.record.RecordingDao" />
+	<bean id="recordingMetaDataDao" class="org.apache.openmeetings.db.dao.record.RecordingMetaDataDao" />
+	<bean id="recordingMetaDeltaDao" class="org.apache.openmeetings.db.dao.record.RecordingMetaDeltaDao" />
+	<bean id="ldapConfigDao" class="org.apache.openmeetings.db.dao.server.LdapConfigDao" />
+	<bean id="invitationManagement" class="org.apache.openmeetings.service.room.InvitationManager" />
+	<bean id="meetingMemberDao" class="org.apache.openmeetings.db.dao.calendar.MeetingMemberDao" />
+	<bean id="privateMessageFolderDao" class="org.apache.openmeetings.db.dao.user.PrivateMessageFolderDao" />
+	<bean id="privateMessageDao" class="org.apache.openmeetings.db.dao.user.PrivateMessageDao" />
+	<bean id="soapLoginDao" class="org.apache.openmeetings.db.dao.server.SOAPLoginDao" />
+	<bean id="userContactDao" class="org.apache.openmeetings.db.dao.user.UserContactDao" />
+	<bean id="userDao" class="org.apache.openmeetings.db.dao.user.UserDao" />
+	<bean id="serverDao" class="org.apache.openmeetings.db.dao.server.ServerDao" />
+	<bean id="chatDao" class="org.apache.openmeetings.db.dao.basic.ChatDao" />
+	<bean id="clientDao" class="org.apache.openmeetings.db.dao.room.ClientDao" />
+	<bean id="mailMessageDao" class="org.apache.openmeetings.db.dao.basic.MailMessageDao" />
+	<bean id="oauth2Dao" class="org.apache.openmeetings.db.dao.server.OAuth2Dao" />
+	<bean id="omCalendarDao" class="org.apache.openmeetings.db.dao.calendar.OmCalendarDao" />
+
+	<!-- No Interface -->
+	<bean id="imageConverter" class="org.apache.openmeetings.core.converter.ImageConverter" />
+	<bean id="documentConverter" class="org.apache.openmeetings.core.converter.DocumentConverter" />
+	<bean id="smsHandler" class="org.apache.openmeetings.core.mail.SMSHandler" />
+	<bean id="importInitvalues" class="org.apache.openmeetings.installation.ImportInitvalues" />
+	<bean id="ldapLoginManagement" class="org.apache.openmeetings.core.ldap.LdapLoginManagement" />
+	<bean id="timezoneUtil" class="org.apache.openmeetings.db.util.TimezoneUtil" />
+	<bean id="backupExport" class="org.apache.openmeetings.backup.BackupExport" />
+	<bean id="backupImport" class="org.apache.openmeetings.backup.BackupImport" />
+	<bean id="appointmentManager" class="org.apache.openmeetings.service.calendar.caldav.AppointmentManager" destroy-method="destroy"/>
+	<bean id="iCalUtils" class="org.apache.openmeetings.service.calendar.caldav.iCalUtils"/>
+
+	<!-- Thread Executor -->
+	<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
+		<property name="corePoolSize" value="5" />
+		<property name="maxPoolSize" value="10" />
+		<property name="queueCapacity" value="25" />
+	</bean>
+
+	<!-- CXF beans -->
+	<bean id="calendarWebService" class="org.apache.openmeetings.webservice.CalendarWebService" />
+	<bean id="errorWebService" class="org.apache.openmeetings.webservice.ErrorWebService" />
+	<bean id="fileWebService" class="org.apache.openmeetings.webservice.FileWebService" />
+	<bean id="groupWebService" class="org.apache.openmeetings.webservice.GroupWebService" />
+	<bean id="infoWebService" class="org.apache.openmeetings.webservice.InfoWebService" />
+	<bean id="recordWebService" class="org.apache.openmeetings.webservice.RecordingWebService" />
+	<bean id="roomWebService" class="org.apache.openmeetings.webservice.RoomWebService" />
+	<bean id="serverWebService" class="org.apache.openmeetings.webservice.ServerWebService" />
+	<bean id="userWebService" class="org.apache.openmeetings.webservice.UserWebService" />
+	<bean id="netTestWebService" class="org.apache.openmeetings.webservice.NetTestWebService" />
+	
+	<!-- (writeXsiType=false) -->
+	<jaxrs:server id="server" address="/">
+		<jaxrs:serviceBeans>
+			<ref bean="calendarWebService"/>
+			<ref bean="errorWebService"/>
+			<ref bean="fileWebService"/>
+			<ref bean="groupWebService"/>
+			<ref bean="infoWebService"/>
+			<ref bean="recordWebService"/>
+			<ref bean="roomWebService"/>
+			<ref bean="serverWebService"/>
+			<ref bean="userWebService"/>
+			<ref bean="netTestWebService"/> <!-- JaxRs only -->
+		</jaxrs:serviceBeans>
+		<jaxrs:providers>
+			<bean id="appDtoMessageBodyWriter" class="org.apache.openmeetings.webservice.util.AppointmentMessageBodyWriter" />
+			<bean id="appDtoListMessageBodyWriter" class="org.apache.openmeetings.webservice.util.AppointmentListMessageBodyWriter" />
+			<bean id="omParamProvider" class="org.apache.openmeetings.webservice.util.OmParamConverterProvider"/>
+		</jaxrs:providers>
+	</jaxrs:server>
+	<jaxws:endpoint id="calendarServiceWS" address="/CalendarService" implementor="#calendarWebService"/>
+	<jaxws:endpoint id="errorServiceWS" address="/ErrorService" implementor="#errorWebService" />
+	<jaxws:endpoint id="groupServiceWS" address="/GroupService" implementor="#groupWebService" />
+	<jaxws:endpoint id="infoServiceWS" address="/InfoService" implementor="#infoWebService" />
+	<jaxws:endpoint id="fileServiceWS" address="/FileService" implementor="#fileWebService" />
+	<jaxws:endpoint id="recordServiceWS" address="/RecordService" implementor="#recordWebService" />
+	<jaxws:endpoint id="roomServiceWS" address="/RoomService" implementor="#roomWebService" />
+	<jaxws:endpoint id="serverServiceWS" address="/ServerService" implementor="#serverWebService" />
+	<jaxws:endpoint id="userServiceWS" address="/UserService" implementor="#userWebService" />
+</beans>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
deleted file mode 100644
index 1a9fe7c..0000000
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
+++ /dev/null
@@ -1,261 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xmlns:tx="http://www.springframework.org/schema/tx"
-	xmlns:context="http://www.springframework.org/schema/context"
-	xmlns:jaxrs="http://cxf.apache.org/jaxrs"
-	xmlns:jaxws="http://cxf.apache.org/jaxws"
-	xmlns:p="http://www.springframework.org/schema/p"
-	xsi:schemaLocation="
-		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
-		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
-		http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
-		http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"
-		>
-	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
-		<property name="persistenceUnitName" value="openmeetings" />
-	</bean>
-	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
-		<property name="entityManagerFactory" ref="entityManagerFactory" />
-	</bean>
-	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
-
-	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
-	<context:annotation-config />
-	<context:component-scan base-package="org.apache.openmeetings" />
-
-	<!-- New Class for the Streaming Handlers -->
-	<bean id="web.handler" class="org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter" />
-
-	<!-- Session configuration start -->
-
-	<bean id="openmeetings.SessionManager" class="org.apache.openmeetings.core.session.SessionManager">
-		<property name="cache">
-			<!-- Memory based session cache by default -->
-			<ref bean="openmeetings.HashMapStore" />
-			<!-- The following section should be used in clustering mode
-			<ref bean="openmeetings.DatabaseStore" />
-			-->
-		</property>
-	</bean>
-
-	<!-- Singleton for memory based cache -->
-	<bean id="openmeetings.HashMapStore" scope="singleton" class="org.apache.openmeetings.core.session.store.HashMapStore" />
-	<!-- Database cache -->
-	<bean id="openmeetings.DatabaseStore" class="org.apache.openmeetings.core.session.store.DatabaseStore" />
-	
-	<bean id="whiteboardCache" scope="singleton" class="org.apache.openmeetings.core.data.whiteboard.WhiteboardCache" />
-
-	<!-- Cluster related config start -->
-	<bean id="openmeetings.ServerUtil" scope="singleton" class="org.apache.openmeetings.core.session.ServerUtil">
-		<!-- Need to be uncommented and set to the real ID if in cluster mode
-		<property name="serverId" value="1" />
-		-->
-	</bean>
-
-	<!-- Start of Services -->
-	<bean id="xmlcrm.service" class="org.apache.openmeetings.core.remote.MainService" />
-	<bean id="userservice.service" class="org.apache.openmeetings.core.remote.UserService" />
-	<bean id="fileservice.service" class="org.apache.openmeetings.core.remote.ConferenceLibrary" />
-	<bean id="openmeetings.FileProcessor" class="org.apache.openmeetings.core.data.file.FileProcessor" />
-	<bean id="openmeetings.FlvExplorerConverter" class="org.apache.openmeetings.core.converter.FlvExplorerConverter" />
-	<bean id="recordingservice.service" class="org.apache.openmeetings.core.remote.RecordingService" />
-	<bean id="mobile.service" class="org.apache.openmeetings.core.remote.MobileService" />
-	<bean id="openmeetings.RecordingConverterTask" class="org.apache.openmeetings.core.data.record.converter.RecordingConverterTask" />
-	<bean id="openmeetings.InterviewConverterTask" class="org.apache.openmeetings.core.data.record.converter.InterviewConverterTask" />
-	<bean id="openmeetings.InterviewConverter" class="org.apache.openmeetings.core.converter.InterviewConverter" />
-	<bean id="openmeetings.RecordingConverter" class="org.apache.openmeetings.core.converter.RecordingConverter" />
-	<bean id="openmeetings.SlaveHTTPConnectionManager" class="org.apache.openmeetings.webservice.cluster.SlaveHTTPConnectionManager" />
-
-	 <!--	1800000 == 30 min
-	 		3600000 == 1 hour
-	 		5000	== 5 sec
-	 		300000	== 5 min
-	 		900000	== 15 min
-	 -->
-	<bean id="cleanupJob" class="org.apache.openmeetings.service.quartz.scheduler.CleanupJob"
-			p:sessionTimeout="1800000" p:testSetupTimeout="3600000" p:roomFilesTtl="3600000" />
-	<bean id="cleanSessionsJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="cleanupJob" p:targetMethod="cleanSessions" p:concurrent="false" />
-	<bean id="triggerCleanSessions" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="cleanSessionsJobDetails" p:startDelay="5000" p:repeatInterval="300000" />
-	<bean id="cleanTestSetupJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="cleanupJob" p:targetMethod="cleanTestSetup" p:concurrent="false" />
-	<bean id="triggerCleanTestSetup" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="cleanTestSetupJobDetail" p:startDelay="1800000" p:repeatInterval="1800000" />
-	<bean id="cleanRoomFilesJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="cleanupJob" p:targetMethod="cleanRoomFiles" p:concurrent="false" />
-	<bean id="triggerCleanRoomFiles" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="cleanRoomFilesJobDetail" p:startDelay="10000" p:repeatInterval="1800000" /> <!-- p:startDelay="1800000" -->
-	<bean id="cleanExpiredRecJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="cleanupJob" p:targetMethod="cleanExpiredRecordings" p:concurrent="false" />
-	<bean id="triggerCleanExpiredRec" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="cleanExpiredRecJobDetails" p:startDelay="5000" p:repeatInterval="3600000" />
-
-	<bean id="reminderJob" class="org.apache.openmeetings.service.quartz.scheduler.ReminderJob"/>
-	<bean id="meetingReminderJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="reminderJob" p:targetMethod="remindMeetings" p:concurrent="false" />
-	<bean id="triggerMeetingReminder" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="meetingReminderJobDetail" p:startDelay="5000" p:repeatInterval="100000"/>
-	<bean id="expiringRecordingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="reminderJob" p:targetMethod="remindExpiringRecordings" p:concurrent="false" />
-	<bean id="triggerExpiringRecording" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="expiringRecordingJobDetail" p:startDelay="5000" p:repeatInterval="3600000"/>
-
-	<!-- Mail related jobs -->
-	<bean id="mailHandler" class="org.apache.openmeetings.core.mail.MailHandler" />
-	<bean id="resetSendingMailStatus" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="mailHandler" p:targetMethod="resetSendingStatus" p:concurrent="false" />
-	<bean id="triggerResetSendingMailStatus" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="resetSendingMailStatus" p:startDelay="60000" p:repeatInterval="900000" />
-	<bean id="sendMails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
-			p:targetObject-ref="mailHandler" p:targetMethod="sendMails" p:concurrent="false" />
-	<bean id="triggerSendMails" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
-			p:jobDetail-ref="sendMails" p:startDelay="60000" p:repeatInterval="60000" />
-	
-	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
-		<property name="triggers">
-			<list>
-				<ref bean="triggerCleanSessions" />
-				<ref bean="triggerCleanTestSetup" />
-				<ref bean="triggerCleanRoomFiles" />
-				<ref bean="triggerCleanExpiredRec" />
-				<ref bean="triggerMeetingReminder" />
-				<ref bean="triggerExpiringRecording" />
-				<ref bean="triggerResetSendingMailStatus" />
-				<ref bean="triggerSendMails" />
-			</list>
-		</property>
-	</bean>
-	<!-- End of Services -->
-
-	<!-- Interface Transactional -->
-	<bean id="roommanagement" class="org.apache.openmeetings.core.data.conference.RoomManager" />
-	<bean id="roomDao" class="org.apache.openmeetings.db.dao.room.RoomDao"/>
-	<bean id="sipDao" class="org.apache.openmeetings.db.dao.room.SipDao">
-	<!--  Should be uncommented and updated with real values for Asterisk
-		<constructor-arg><value>127.0.0.1</value></constructor-arg>
-		<constructor-arg><value>5038</value></constructor-arg>
-		<constructor-arg><value>openmeetings</value></constructor-arg>
-		<constructor-arg><value>12345</value></constructor-arg>
-		<constructor-arg><value>10000</value></constructor-arg>
-	 -->
-	</bean>
-	<bean id="invitationDao" class="org.apache.openmeetings.db.dao.room.InvitationDao" />
-	<bean id="groupDao" class="org.apache.openmeetings.db.dao.user.GroupDao" />
-	<bean id="groupUserDao" class="org.apache.openmeetings.db.dao.user.GroupUserDao" />
-	<bean id="errorManagement" class="org.apache.openmeetings.db.dao.basic.ErrorDao" />
-	<bean id="navimanagement" class="org.apache.openmeetings.db.dao.basic.NavigationDao" />
-	<bean id="pollManagement" class="org.apache.openmeetings.db.dao.room.PollDao" />
-	<bean id="labelDao" class="org.apache.openmeetings.db.dao.label.LabelDao" />
-	<bean id="configurationDaoImpl" class="org.apache.openmeetings.db.dao.basic.ConfigurationDao" />
-	<bean id="appointmentDao" class="org.apache.openmeetings.db.dao.calendar.AppointmentDao" />
-	<bean id="appointmentLogic" class="org.apache.openmeetings.service.calendar.AppointmentLogic" />
-	<bean id="sessionManagement" class="org.apache.openmeetings.db.dao.server.SessiondataDao" />
-	<bean id="userManagement" class="org.apache.openmeetings.service.user.UserManager" />
-	<bean id="roomModeratorDao" class="org.apache.openmeetings.db.dao.room.RoomModeratorDao" />
-	<bean id="roomGroupDao" class="org.apache.openmeetings.db.dao.room.RoomGroupDao"/>
-	<bean id="conferenceLogDao" class="org.apache.openmeetings.db.dao.log.ConferenceLogDao" />
-	<bean id="emailManagement" class="org.apache.openmeetings.service.mail.EmailManager" />
-	<bean id="fileItemLogDao" class="org.apache.openmeetings.db.dao.file.FileItemLogDao" />
-	<bean id="fileExplorerItemDao" class="org.apache.openmeetings.db.dao.file.FileExplorerItemDao" />
-	<bean id="recordingDao" class="org.apache.openmeetings.db.dao.record.RecordingDao" />
-	<bean id="recordingMetaDataDao" class="org.apache.openmeetings.db.dao.record.RecordingMetaDataDao" />
-	<bean id="recordingMetaDeltaDao" class="org.apache.openmeetings.db.dao.record.RecordingMetaDeltaDao" />
-	<bean id="ldapConfigDao" class="org.apache.openmeetings.db.dao.server.LdapConfigDao" />
-	<bean id="invitationManagement" class="org.apache.openmeetings.service.room.InvitationManager" />
-	<bean id="meetingMemberDao" class="org.apache.openmeetings.db.dao.calendar.MeetingMemberDao" />
-	<bean id="privateMessageFolderDao" class="org.apache.openmeetings.db.dao.user.PrivateMessageFolderDao" />
-	<bean id="privateMessageDao" class="org.apache.openmeetings.db.dao.user.PrivateMessageDao" />
-	<bean id="soapLoginDao" class="org.apache.openmeetings.db.dao.server.SOAPLoginDao" />
-	<bean id="userContactDao" class="org.apache.openmeetings.db.dao.user.UserContactDao" />
-	<bean id="userDao" class="org.apache.openmeetings.db.dao.user.UserDao" />
-	<bean id="serverDao" class="org.apache.openmeetings.db.dao.server.ServerDao" />
-	<bean id="chatDao" class="org.apache.openmeetings.db.dao.basic.ChatDao" />
-	<bean id="clientDao" class="org.apache.openmeetings.db.dao.room.ClientDao" />
-	<bean id="mailMessageDao" class="org.apache.openmeetings.db.dao.basic.MailMessageDao" />
-	<bean id="oauth2Dao" class="org.apache.openmeetings.db.dao.server.OAuth2Dao" />
-	<bean id="omCalendarDao" class="org.apache.openmeetings.db.dao.calendar.OmCalendarDao" />
-
-	<!-- No Interface -->
-	<bean id="imageConverter" class="org.apache.openmeetings.core.converter.ImageConverter" />
-	<bean id="documentConverter" class="org.apache.openmeetings.core.converter.DocumentConverter" />
-	<bean id="smsHandler" class="org.apache.openmeetings.core.mail.SMSHandler" />
-	<bean id="importInitvalues" class="org.apache.openmeetings.installation.ImportInitvalues" />
-	<bean id="ldapLoginManagement" class="org.apache.openmeetings.core.ldap.LdapLoginManagement" />
-	<bean id="timezoneUtil" class="org.apache.openmeetings.db.util.TimezoneUtil" />
-	<bean id="whiteboardManager" class="org.apache.openmeetings.core.data.whiteboard.WhiteboardManager" />
-	<bean id="backupExport" class="org.apache.openmeetings.backup.BackupExport" />
-	<bean id="backupImport" class="org.apache.openmeetings.backup.BackupImport" />
-	<bean id="appointmentManager" class="org.apache.openmeetings.service.calendar.caldav.AppointmentManager" destroy-method="destroy"/>
-	<bean id="iCalUtils" class="org.apache.openmeetings.service.calendar.caldav.iCalUtils"/>
-
-	<!-- Thread Executor -->
-	<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
-		<property name="corePoolSize" value="5" />
-		<property name="maxPoolSize" value="10" />
-		<property name="queueCapacity" value="25" />
-	</bean>
-
-	<!-- CXF beans -->
-	<bean id="calendarWebService" class="org.apache.openmeetings.webservice.CalendarWebService" />
-	<bean id="errorWebService" class="org.apache.openmeetings.webservice.ErrorWebService" />
-	<bean id="fileWebService" class="org.apache.openmeetings.webservice.FileWebService" />
-	<bean id="groupWebService" class="org.apache.openmeetings.webservice.GroupWebService" />
-	<bean id="infoWebService" class="org.apache.openmeetings.webservice.InfoWebService" />
-	<bean id="recordWebService" class="org.apache.openmeetings.webservice.RecordingWebService" />
-	<bean id="roomWebService" class="org.apache.openmeetings.webservice.RoomWebService" />
-	<bean id="serverWebService" class="org.apache.openmeetings.webservice.ServerWebService" />
-	<bean id="userWebService" class="org.apache.openmeetings.webservice.UserWebService" />
-	<bean id="netTestWebService" class="org.apache.openmeetings.webservice.NetTestWebService" />
-	
-	<!-- (writeXsiType=false) -->
-	<jaxrs:server id="server" address="/">
-		<jaxrs:serviceBeans>
-			<ref bean="calendarWebService"/>
-			<ref bean="errorWebService"/>
-			<ref bean="fileWebService"/>
-			<ref bean="groupWebService"/>
-			<ref bean="infoWebService"/>
-			<ref bean="recordWebService"/>
-			<ref bean="roomWebService"/>
-			<ref bean="serverWebService"/>
-			<ref bean="userWebService"/>
-			<ref bean="netTestWebService"/> <!-- JaxRs only -->
-		</jaxrs:serviceBeans>
-		<jaxrs:providers>
-			<bean id="appDtoMessageBodyWriter" class="org.apache.openmeetings.webservice.util.AppointmentMessageBodyWriter" />
-			<bean id="appDtoListMessageBodyWriter" class="org.apache.openmeetings.webservice.util.AppointmentListMessageBodyWriter" />
-			<bean id="omParamProvider" class="org.apache.openmeetings.webservice.util.OmParamConverterProvider"/>
-		</jaxrs:providers>
-	</jaxrs:server>
-	<jaxws:endpoint id="calendarServiceWS" address="/CalendarService" implementor="#calendarWebService"/>
-	<jaxws:endpoint id="errorServiceWS" address="/ErrorService" implementor="#errorWebService" />
-	<jaxws:endpoint id="groupServiceWS" address="/GroupService" implementor="#groupWebService" />
-	<jaxws:endpoint id="infoServiceWS" address="/InfoService" implementor="#infoWebService" />
-	<jaxws:endpoint id="fileServiceWS" address="/FileService" implementor="#fileWebService" />
-	<jaxws:endpoint id="recordServiceWS" address="/RecordService" implementor="#recordWebService" />
-	<jaxws:endpoint id="roomServiceWS" address="/RoomService" implementor="#roomWebService" />
-	<jaxws:endpoint id="serverServiceWS" address="/ServerService" implementor="#serverWebService" />
-	<jaxws:endpoint id="userServiceWS" address="/UserService" implementor="#userWebService" />
-</beans>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/webapp/WEB-INF/red5-web.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/red5-web.xml b/openmeetings-web/src/main/webapp/WEB-INF/red5-web.xml
index 6b2df68..b265961 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/red5-web.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/red5-web.xml
@@ -37,5 +37,5 @@
 		<property name="virtualHosts" value="${webapp.virtualHosts}" />
 	</bean>
 
-	<import resource="classes/openmeetings-applicationContext.xml" />
+	<import resource="classes/applicationContext.xml" />
 </beans>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/web.xml b/openmeetings-web/src/main/webapp/WEB-INF/web.xml
index 973ef1c..2871563 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/web.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/web.xml
@@ -35,7 +35,7 @@
 		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
 		<init-param>
 			<param-name>config-location</param-name>
-			<param-value>classpath:openmeetings-applicationContext.xml</param-value>
+			<param-value>classpath:applicationContext.xml</param-value>
 		</init-param>
 		<load-on-startup>1</load-on-startup>
 		<async-supported>true</async-supported>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractSpringTest.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractSpringTest.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractSpringTest.java
index 96e7d3f..c7fcea4 100644
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractSpringTest.java
+++ b/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractSpringTest.java
@@ -32,7 +32,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @TestExecutionListeners({})
-@ContextConfiguration(locations={"classpath:openmeetings-applicationContext.xml"}, inheritLocations = true)
+@ContextConfiguration(locations={"classpath:applicationContext.xml"}, inheritLocations = true)
 public abstract class AbstractSpringTest extends AbstractJUnit4SpringContextTests {
 
 	@BeforeClass

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/b1c60093/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 255937b..bbcf269 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,7 +40,7 @@
 		<maven.javadoc.version>2.10.3</maven.javadoc.version>
 		<maven.surefire.version>2.19.1</maven.surefire.version>
 		<maven-site.version>3.3</maven-site.version>
-		<wicket.version>8.0.0-M5</wicket.version>
+		<wicket.version>8.0.0-SNAPSHOT</wicket.version>
 		<wicketju.version>8.0.0-M5</wicketju.version>
 		<wickets.version>8.0.0-M5</wickets.version>
 		<red5-server.version>1.0.9-M6</red5-server.version>


[11/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] clear all/slide is implemented, couple of issues are fixed

Posted by so...@apache.org.
[OPENMEETINGS-551] clear all/slide is implemented, couple of issues are fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/8a900e52
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/8a900e52
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/8a900e52

Branch: refs/heads/master
Commit: 8a900e5226ad1bfaac3fae0260a05d9655ea6d0c
Parents: 821bc0a
Author: Maxim Solodovnik <so...@apache.org>
Authored: Mon Apr 3 16:38:44 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Mon Apr 3 16:38:44 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/db/dto/room/Whiteboard.java    |   5 +-
 .../openmeetings/web/room/wb/WbPanel.html       |   8 +-
 .../openmeetings/web/room/wb/WbPanel.java       |  16 +++
 .../org/apache/openmeetings/web/room/wb/wb.js   | 113 +++++++++++++++----
 4 files changed, 117 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8a900e52/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
index 3f16125..c4a3df8 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
@@ -20,11 +20,12 @@ package org.apache.openmeetings.db.dto.room;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
+import java.util.Collections;
 import java.util.Date;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -38,7 +39,7 @@ public class Whiteboard {
 	private Integer y = 0;
 	private Integer zoom = 100;
 	private Boolean fullFit = true;
-	private Map<String, JSONObject> roomItems = new ConcurrentHashMap<>();
+	private Map<String, JSONObject> roomItems = Collections.synchronizedMap(new LinkedHashMap<>());
 	private Date created = new Date();
 	private int slide = 0;
 	private int zIndex = 1;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8a900e52/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
index 92963b6..f464953 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
@@ -59,9 +59,7 @@
 		<div id="wb-tools" class="tools ui-state-active vertical clear" style="position: absolute; top: 20px; right: 0px;">
 			<div class="bumper"></div>
 			<div wicket:message="title:62" class="ui-widget-header clickable om-icon big clear-all"></div>
-<!-- clear-all confirnmation: 1340 -->
 			<div wicket:message="title:1005" class="ui-widget-header clickable om-icon big clear-slide"></div>
-<!-- clear-slide confirmation 1359 -->
 			<div wicket:message="title:197" class="ui-widget-header clickable om-icon big save"></div>
 <!-- save-as filename -->
 			<div wicket:message="title:70" class="ui-widget-header clickable om-icon big undo"></div>
@@ -113,6 +111,12 @@
 				</div>
 			</div>
 		</div>
+		<div id="clear-all-confirm" wicket:message="title:1339, data-btn-ok:54, data-btn-cancel:55">
+			<wicket:message key="1340"/>
+		</div>
+		<div id="clear-slide-confirm" wicket:message="title:1339, data-btn-ok:54, data-btn-cancel:55">
+			<wicket:message key="1359"/>
+		</div>
 	</div>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8a900e52/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index c446ead..ad438ff 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -87,6 +87,8 @@ public class WbPanel extends Panel {
 		, createObj
 		, modifyObj
 		, deleteObj
+		, clearAll
+		, clearSlide
 	}
 	private final AbstractDefaultAjaxBehavior wbAction = new AbstractDefaultAjaxBehavior() {
 		private static final long serialVersionUID = 1L;
@@ -176,6 +178,20 @@ public class WbPanel extends Panel {
 							sendWbAll("WbArea.removeObj", obj);
 						}
 							break;
+						case clearAll:
+						{
+							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
+							wb.clear();
+							sendWbAll("WbArea.clearAll", obj);
+						}
+							break;
+						case clearSlide:
+						{
+							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
+							wb.entrySet().removeIf(e -> e.getValue().optInt("slide", -1) == obj.getInt("slide"));
+							sendWbAll("WbArea.clearSlide", obj);
+						}
+							break;
 					}
 				}
 			} catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/8a900e52/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index 64ee00d..ec7ad9a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -507,12 +507,12 @@ var Wb = function() {
 		}).click(function() {
 			var b = getBtn();
 			if (b.length && b.hasClass(ACTIVE)) {
-				b.data('deactivate')();
+				b.data().deactivate();
 			}
-			btn.data('activate')();
+			btn.data().activate();
 		});
 		if (def) {
-			btn.data('activate')();
+			btn.data().activate();
 		}
 	}
 	function initCliparts() {
@@ -530,6 +530,27 @@ var Wb = function() {
 			initToolBtn(cur.data('mode'), false, Clipart(wb, cur));
 		});
 	}
+	function confirmDlg(_id, okHandler) {
+		var confirm = $('#' + _id);
+		confirm.dialog({
+			modal: true
+			, buttons: [
+				{
+					text: confirm.data('btn-ok')
+					, click: function() {
+						okHandler();
+						$(this).dialog("close");
+					}
+				}
+				, {
+					text: confirm.data('btn-cancel')
+					, click: function() {
+						$(this).dialog("close");
+					}
+				}
+			]
+		});
+	}
 	function internalInit() {
 		t.draggable({
 			snap: "parent"
@@ -560,6 +581,12 @@ var Wb = function() {
 			t.find(".om-icon.settings").click(function() {
 				s.show();
 			});
+			t.find('.om-icon.clear-all').click(function() {
+				confirmDlg('clear-all-confirm', function() { wbAction('clearAll', JSON.stringify({wbId: wb.id})); });
+			});
+			t.find('.om-icon.clear-slide').click(function() {
+				confirmDlg('clear-slide-confirm', function() { wbAction('clearSlide', JSON.stringify({wbId: wb.id, slide: slide})); });
+			});
 			s.find('.wb-prop-b, .wb-prop-i')
 				.button()
 				.click(function() {
@@ -670,6 +697,7 @@ var Wb = function() {
 				break;
 			case 'Presentation':
 			{
+				var ccount = canvases.length;
 				minWidth = Math.max(minWidth, _o.width);
 				minHeight = Math.max(minHeight, _o.height);
 				width = Math.max(minWidth, width);
@@ -683,6 +711,13 @@ var Wb = function() {
 					canvas.setBackgroundImage(_o._src + "&slide=" + i, canvas.renderAll.bind(canvas), {})
 							.setWidth(width).setHeight(height);
 				}
+				if (ccount != canvases.length) {
+					var b = getBtn();
+					if (b.length && b.hasClass(ACTIVE)) {
+						b.data().deactivate();
+						b.data().activate();
+					}
+				}
 			}
 				break;
 			default:
@@ -797,16 +832,7 @@ var Wb = function() {
 		var obj = e.target;
 		console.log('Text Changed', obj);
 	};*/
-	function addCanvas() {
-		var sl = canvases.length;
-		var cid = 'can-' + a.attr('id') + '-slide-' + sl;
-		var c = $('<canvas></canvas>').attr('id', cid);
-		a.find('.canvases').append(c);
-		var canvas = new fabric.Canvas(c.attr('id'));
-		canvas.wbId = wb.id;
-		canvas.slide = sl;
-		canvases.push(canvas);
-		//TODO create via WS canvas:cleared
+	function setHandlers(canvas) {
 		if (readOnly) {
 			canvas.off({
 				'object:added': objAddedHandler
@@ -828,6 +854,16 @@ var Wb = function() {
 				, 'wb:object:created': wbObjCreatedHandler
 			});
 		}
+	}
+	function addCanvas() {
+		var sl = canvases.length;
+		var cid = 'can-' + a.attr('id') + '-slide-' + sl;
+		var c = $('<canvas></canvas>').attr('id', cid);
+		a.find('.canvases').append(c);
+		var canvas = new fabric.Canvas(c.attr('id'));
+		canvas.wbId = wb.id;
+		canvas.slide = sl;
+		canvases.push(canvas);
 		var cc = $('#' + cid).closest('.canvas-container');
 		if (readOnly) {
 			if (sl == slide) {
@@ -836,6 +872,7 @@ var Wb = function() {
 				cc.hide();
 			}
 		}
+		setHandlers(canvas);
 	}
 	wb.setReadOnly = function(ro) {
 		if (readOnly != ro) {
@@ -859,14 +896,17 @@ var Wb = function() {
 			}
 			showCurentSlide();
 			t = a.find('.tools'), s = a.find(".wb-settings");
+			wb.eachCanvas(function(canvas) {
+				setHandlers(canvas);
+			});
 			internalInit();
 		}
 	};
 	wb.init = function(_wbId, tid, ro) {
 		wb.id = _wbId;
 		a = $('#' + tid);
-		wb.setReadOnly(ro);
 		addCanvas();
+		wb.setReadOnly(ro);
 	};
 	wb.resize = function(w, h) {
 		if (t.position().left + t.width() > a.width()) {
@@ -937,6 +977,28 @@ var Wb = function() {
 			_removeHandler(arr[i]);
 		}
 	};
+	wb.clearAll = function() {
+		for (var i = 1; i < canvases.length; ++i) {
+			var cc = $('#can-wb-tab-0-slide-' + i).closest('.canvas-container');
+			cc.remove();
+			canvases[i].dispose();
+		}
+		canvases.splice(1);
+		canvases[0].clear();
+		minWidth = minHeight = 0;
+	};
+	wb.clearSlide = function(_sl) {
+		if (canvases.length > _sl) {
+			var canvas = canvases[_sl];
+			canvas.renderOnAddRemove = false;
+			var arr = canvas.getObjects();
+			while (arr.length > 0) {
+				arr[arr.length - 1].remove();
+			}
+			canvas.renderOnAddRemove = true;
+			canvas.renderAll();
+		}
+	};
 	wb.getCanvas = function() {
 		return canvases[slide];
 	};
@@ -1029,12 +1091,14 @@ var WbArea = (function() {
 	};
 	self.setReadOnly = function(ro) {
 		readOnly = ro;
-		tabs.find(".ui-tabs-nav").sortable(readOnly ? "disable" : "enable");
+		var tabsNav = tabs.find(".ui-tabs-nav");
+		tabsNav.sortable(readOnly ? "disable" : "enable");
 		var prev = tabs.find('.prev.om-icon'), next = tabs.find('.next.om-icon');
 		if (readOnly) {
 			if (prev.length > 0) {
 				prev.parent().remove();
 				next.parent().remove();
+				tabsNav.find('li button').remove();
 			}
 			$(window).off('keyup', deleteHandler);
 		} else {
@@ -1052,6 +1116,12 @@ var WbArea = (function() {
 				tabs.find('.next.om-icon').click(function() {
 					scroll.scrollLeft(scroll.scrollLeft() + 30);
 				});
+				tabsNav.find('li').each(function(idx) {
+					$(this).append($('#wb-tab-close').clone().attr('id', ''));
+					$(this).find('button').click(function() {
+						wbAction('removeWb', JSON.stringify({id: obj.id}));
+					});
+				});
 				$(window).keyup(deleteHandler);
 			}
 		}
@@ -1091,12 +1161,6 @@ var WbArea = (function() {
 			, li = $('#wb-area-tab').clone().attr('id', '').data('wb-id', obj.id)
 			, wb = $('#wb-area').clone().attr('id', tid);
 		li.find('a').text(obj.name).attr('title', obj.name).attr('href', "#" + tid);
-		if (!readOnly) {
-			li.append($('#wb-tab-close').clone().attr('id', ''));
-			li.find('button').click(function() {
-				wbAction('removeWb', JSON.stringify({id: obj.id}));
-			});
-		}
 	
 		tabs.find(".ui-tabs-nav").append(li);
 		tabs.append(wb);
@@ -1129,6 +1193,13 @@ var WbArea = (function() {
 	self.removeObj = function(json) {
 		self.getWb(json.wbId).removeObj(json.obj);
 	};
+	self.clearAll = function(json) {
+		self.getWb(json.wbId).clearAll();
+		setRoomSizes();
+	};
+	self.clearSlide = function(json) {
+		self.getWb(json.wbId).clearSlide(json.slide);
+	};
 	self.remove = function(obj) {
 		var tabId = self.getWbTabId(obj.id);
 		tabs.find('li[aria-controls="' + tabId + '"]').remove();


[28/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] network testing is fixed

Posted by so...@apache.org.
[OPENMEETINGS-551] network testing is fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/c79c1213
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/c79c1213
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/c79c1213

Branch: refs/heads/master
Commit: c79c121387ab20014f49cabd57fbc82ba906d54e
Parents: 838bfbe
Author: Maxim Solodovnik <so...@apache.org>
Authored: Thu Apr 13 17:35:27 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Thu Apr 13 17:35:27 2017 +0000

----------------------------------------------------------------------
 .../swf10/networkTesting/networktesting.lzx     |  84 +--
 .../swf10/networkTesting/rtmpConnection.lzx     | 654 +++++++++----------
 .../apache/openmeetings/web/room/SwfPanel.java  |  63 +-
 .../openmeetings/web/room/VideoSettings.java    |   2 +-
 .../openmeetings/web/room/swf-functions.js      |  11 +-
 5 files changed, 392 insertions(+), 422 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c79c1213/openmeetings-flash/src/main/swf10/networkTesting/networktesting.lzx
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/swf10/networkTesting/networktesting.lzx b/openmeetings-flash/src/main/swf10/networkTesting/networktesting.lzx
index acfef7a..df65c1b 100644
--- a/openmeetings-flash/src/main/swf10/networkTesting/networktesting.lzx
+++ b/openmeetings-flash/src/main/swf10/networkTesting/networktesting.lzx
@@ -19,7 +19,6 @@
   
 -->
 <canvas width="100%" height="100%" title="NetworkTesting">
-
 	<switch>
 		<when property="$as3">
 			<passthrough>
@@ -50,7 +49,10 @@
 		for (var i = 0; i < lbls.length; ++i) {
 			canvas.lbls[lbls[i].id] = lbls[i].value;
 		}
+		var config = ExternalInterface.call("getConfig");
 		doDebugInit();
+		getSettings(config);
+		canvas.showTests();
 	]]></handler>
 
 	<method name="lbl" args="key">
@@ -59,60 +61,18 @@
 		return !!s ? s : "Missing[" + key + "]";
 	</method>
 
-	<!--
-		These attributes are rewritten by values from "public/config.xml"
-	-->
-	<attribute name="rtmpProtocol" type="string" value="rtmp" />
-	<attribute name="rtmpHost" type="string" value="" />
-	<attribute name="rtmpPort" type="number" value="1935" />
-	
-	<attribute name="httpProtocol" type="string" value="http" />
-	<attribute name="httpHost" type="string" value="" />
-	<attribute name="httpPort" type="number" value="5080" />
-	<attribute name="uriContext" type="string" value="/openmeetings" />
-	<attribute name="rtmpUriPath" type="string" value="/openmeetings/hibernate" />
-
-	<method name="getBrowserHost">
-		var host:String = ExternalInterface.call("window.location.host.toString()");
-		// in case of IE or some other security issues we will fail ...
-		if (!host) {
-			var url:String = canvas.proxyurl;
-			if (url) {
-				if ($debug) Debug.write("url ", url);
-				var paramsIdx = url.indexOf("?");
-				if (paramsIdx != -1) {
-					url = url.substr(0, paramsIdx);
-				}
-				if ($debug) Debug.write("url ", url);
-				url = url.substr(url.indexOf("//") + 2);
-				var portIdx = url.indexOf(":");
-				host = url.substr(0, portIdx != -1 ? portIdx : url.indexOf("/"));
-				if ($debug) Debug.write("host ", host);
-			}
-		}
-		return host;
-	</method>
-	
-	<method name="getSettings">
-		var settingsPtr = canvas.settings.getPointer();
-		
-		var useSSL:Boolean = ("yes" == settingsPtr.xpathQuery("config/useSSL/text()"));
-		canvas.setAttribute("rtmpProtocol", useSSL ? "rtmps" : "rtmp");
-		canvas.setAttribute("proxyType", settingsPtr.xpathQuery("config/proxyType/text()"));
-		canvas.setAttribute("rtmpHost", settingsPtr.xpathQuery("config/rtmphostlocal/text()"));
-		if (!canvas.rtmpHost) {
-			canvas.rtmpHost = getBrowserHost();
-		}
-		canvas.setAttribute("rtmpPort", settingsPtr.xpathQuery("config/" + (useSSL ? "rtmpsslport" : "rtmpport") + "/text()"));
+	<method name="getSettings" args="config">
+		if ($debug) Debug.write("getSettings:: ", config);
+		canvas.setAttribute("rtmpProtocol", config.flashProtocol);
+		canvas.setAttribute("proxyType", config.proxy);
+		canvas.setAttribute("rtmpHost", config.host);
+		canvas.setAttribute("rtmpPort", config.flashPort);
 		
-		canvas.setAttribute("httpProtocol", settingsPtr.xpathQuery("config/protocol/text()"));
-		canvas.setAttribute("httpHost", settingsPtr.xpathQuery("config/httphostlocal/text()"));
-		if (!canvas.httpHost) {
-			canvas.httpHost = rtmpHost;
-		}
-		canvas.setAttribute("httpPort", settingsPtr.xpathQuery("config/red5httpport/text()"));
+		canvas.setAttribute("httpProtocol", config.httpProtocol);
+		canvas.setAttribute("httpHost", config.host);
+		canvas.setAttribute("httpPort", config.httpPort);
 
-		canvas.setAttribute("uriContext", settingsPtr.xpathQuery("config/httpRootKey/text()"));
+		canvas.setAttribute("uriContext", '/' + config.path);
 		canvas.setAttribute("rtmpUriPath", canvas.uriContext + "hibernate");
 	</method>
 
@@ -121,24 +81,6 @@
 		tests.testAll();
 	</method>
 
-	<dataset type="http" name="settings" request="false" proxied="false">
-		<handler name="oninit">
-			this.setAttribute("src", "config.xml");
-			this.doRequest();
-		</handler>
-		<handler name="ondata">
-			if ($debug) Debug.write("Settings are retrieved");
-			canvas.getSettings();
-			canvas.showTests();
-		</handler>
-		<handler name="onerror" args="e">
-			if ($debug) Debug.write("Settings error [" + this.src + "]", e);
-		</handler>
-		<handler name="ontimeout" args="e">
-			if ($debug) Debug.write("Settings timeout error", e);
-		</handler>
-	</dataset>
-
 	<attribute name="busy" type="boolean" value="false"/>
 	<attribute name="log" type="string" value="" />
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c79c1213/openmeetings-flash/src/main/swf10/networkTesting/rtmpConnection.lzx
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/swf10/networkTesting/rtmpConnection.lzx b/openmeetings-flash/src/main/swf10/networkTesting/rtmpConnection.lzx
index 1cfb69f..ad1958f 100644
--- a/openmeetings-flash/src/main/swf10/networkTesting/rtmpConnection.lzx
+++ b/openmeetings-flash/src/main/swf10/networkTesting/rtmpConnection.lzx
@@ -7,369 +7,361 @@
   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
-    	  
+
+	  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.
-  
--->
 
+-->
 
 <class name="rtmpConnection" extends="node">
-
-        <switch>
-            <when property="$as3">
-                <passthrough>
-                    import flash.net.NetConnection;
-                    import flash.events.NetStatusEvent;
-                </passthrough>
-            </when>
-        </switch>
-
-    	<attribute name="debug" value="false" type="boolean" />
-    	
-    	<event name="onconnect"/>
-    	<event name="onerror"/>
-        
-        <!-- this attribute holds a reference to the current/last called netremoteCall,
-        in case of error you can debug that way which call did fail -->
-        <attribute name="lastCalled" value="null" />
-    	
-    	<attribute name="src" value="" type="string"/>
-
-		<method name="connect">
-            this._nc = new NetConnection();
-
-            // local reference to rtmpconnection
-            //this._nc.t = this;
-            
-            this._nc.proxyType = canvas.proxyType;
-            
-            var ok = this._nc.connect(src == "null" ? null : src, true); //isAVClient = true
-            if (this.debug) {
-            	if($debug) Debug.write("*** debug ***");
-            }
-            
-            this._nc.addEventListener(NetStatusEvent.NET_STATUS, _onStatus);
-            
-    		if($debug) Debug.write("devRtmpConnection/registerMethods()");
-    		var clientObj = {};
-    		clientObj.setId = this.setId;
-    		
-    		this._nc.client = clientObj;
-    		
-			//Register Methods
-			//this.registerMethods();
-		</method>
-		
-		<method name="setId" args="tId">
-			if ($debug) Debug.write("setId ", tId);
-		</method>
-		
-        <method name="_onStatus" args="stats"><![CDATA[
-            if ($debug) {
-                Debug.write("devrtmpconnection", this, "_onStatus", stats.info.code);
-            }
-
-            var msg = "";
-            var s;
-
-            switch (stats.info.code) {
-
-                case "NetConnection.Connect.Success": {
-                    // The connection attempt succeeded.
-                    //canvas.currentNC is the reference to the NetConnection that is used in the NetStream
-                    msg = stats.info.code;
-                    canvas.currentNC = this._nc;
-                    s = 2;
-                    break;
-                }
-                
-                case "NetConnection.Connect.Closed": {
-                    msg = stats.info.code;
-                    this._nc = null;
-                    canvas.currentNC = null;
-                    s = 0;
-                    break;
-                }
-
-                default: {
-                    msg = stats.info.code;
-                    s = 0;
-                    break;
-                }
-
-            }
-
-            this.setAttribute("status", msg);
-
-            if (s == 2) {
-                this.onconnect.sendEvent();
-            } else {
-            	this.onerror.sendEvent();
-            }
-
-          ]]>
-        </method>	
-        
-        <method name="disconnect">
-        	if ($debug) Debug.write(" DISCONNECT ");
-        	if (this._nc != null) {
-                this._nc.close();
-            }
-        </method>
-    <!--- 
-        With this function all methods are registered to the NetConnection
-        A server can invoke this Method with a call for it from the Client
-        Only subnodes of rtmpconnections which are a instance of netRemoteCallHib
-        are registered, to add dynamically methods to the remotefunction you will
-        have to invoke this method once again
-        -swagner
-     -->
-    <method name="registerMethods">
-        <![CDATA[
-	        if (this.subnodes!=null){
-	            var clientObj = {};
-		        //Register all methods which are onstanceof netRemoteCallHib
-		        for (var i=0;i<this.subnodes.length;i++){
-		            //If it is of Type netRemoteCallHib then register it to the NetConnection
-		            if (this.subnodes[i] instanceof lz.netRemoteCallHib){
-		                clientObj[this.subnodes[i].funcname] = function( args ){
-                            return canvas.thishib.remoteCallMethod(arguments.callee,arguments);
-		                    //return hib.remoteCallMethod(arguments.callee,args);
-		                }
-		            }
-		        }
-		        this._nc.client = clientObj;
-        	}
-        ]]>
-    </method>
-    
-    <!-- 
-        Process the RemoteCall to the Right Funtion
-        -swagner
-     -->
-    <method name="remoteCallMethod" args="callee,args">
-        <![CDATA[
-            for (var eg in this._nc){
-                if (this._nc[eg]==callee){
-                    if (this.debug) {
-                        //_root.Debug.write.write("DEBUG invoked a function remotely: ",eg,args);
-                    }    
-                    if (args.length == 1) {
-                        return this.callFuntion(eg,args[0]);
-                    } else {
-                        return this.callFuntion(eg,args);
-                    }
-                    //return this.callFuntion(eg,args);
-                }
-            }
-        ]]>
-    </method>
-    
-    <!-- 
-        Map the Function to a netRemoteCallHib
-        -swagner
-     -->
-    <method name="callFuntion" args="funcname,args">
-        <![CDATA[
-            for (var i=0;i<this.subnodes.length;i++){
-                if (this.subnodes[i].funcname==funcname){
-                    return this.subnodes[i].onResult(args);
-                }
-            }
-        ]]>
-    </method>		
-    
-    <method name="callRPC" args="func, obj, params">
-    	//if ($debug) Debug.write("*** call: func, obj, params",func,obj, typeof (params) ,params.length);
-    	if (params.length != 0){
-	    	//does this really work?
-	    	//ASSetPropFlags(_global, null, 8, 1);
-            //setPropertyIsEnumerable(8, 1);
-	    	//Debug.write("does it work?",arguments);
-	    	<!--
-	    	this._nc.call.apply(this._nc,arguments);
-	    	 -->
+	<switch>
+		<when property="$as3">
+			<passthrough>
+				import flash.net.NetConnection;
+				import flash.events.NetStatusEvent;
+			</passthrough>
+		</when>
+	</switch>
+
+	<attribute name="debug" value="false" type="boolean" />
+
+	<event name="onconnect"/>
+	<event name="onerror"/>
+
+	<!-- this attribute holds a reference to the current/last called netremoteCall,
+	in case of error you can debug that way which call did fail -->
+	<attribute name="lastCalled" value="null" />
+
+	<attribute name="src" value="" type="string"/>
+
+	<method name="connect">
+		this._nc = new NetConnection();
+
+		// local reference to rtmpconnection
+		//this._nc.t = this;
+
+		this._nc.proxyType = canvas.proxyType;
+
+		var ok = this._nc.connect(src == "null" ? null : src, {
+			uid: "noclient"
+		});
+		if (this.debug) {
+			if($debug) Debug.write("*** debug ***");
+		}
+
+		this._nc.addEventListener(NetStatusEvent.NET_STATUS, _onStatus);
+
+		if($debug) Debug.write("devRtmpConnection/registerMethods()");
+		var clientObj = {};
+		clientObj.setId = this.setId;
+
+		this._nc.client = clientObj;
+
+		//Register Methods
+		//this.registerMethods();
+	</method>
+
+	<method name="setId" args="tId">
+		if ($debug) Debug.write("setId ", tId);
+	</method>
+
+	<method name="_onStatus" args="stats"><![CDATA[
+		if ($debug) {
+			Debug.write("devrtmpconnection", this, "_onStatus", stats.info.code);
+		}
+
+		var msg = "";
+		var s;
+
+		switch (stats.info.code) {
+
+			case "NetConnection.Connect.Success": {
+				// The connection attempt succeeded.
+				//canvas.currentNC is the reference to the NetConnection that is used in the NetStream
+				msg = stats.info.code;
+				canvas.currentNC = this._nc;
+				s = 2;
+				break;
+			}
+
+			case "NetConnection.Connect.Closed": {
+				msg = stats.info.code;
+				this._nc = null;
+				canvas.currentNC = null;
+				s = 0;
+				break;
+			}
+
+			default: {
+				msg = stats.info.code;
+				s = 0;
+				break;
+			}
+
+		}
+
+		this.setAttribute("status", msg);
+
+		if (s == 2) {
+			this.onconnect.sendEvent();
+		} else {
+			this.onerror.sendEvent();
+		}
+
+	]]>
+	</method>
+
+	<method name="disconnect">
+		if ($debug) Debug.write(" DISCONNECT ");
+		if (this._nc != null) {
+			this._nc.close();
+		}
+	</method>
+	<!---
+		With this function all methods are registered to the NetConnection
+		A server can invoke this Method with a call for it from the Client
+		Only subnodes of rtmpconnections which are a instance of netRemoteCallHib
+		are registered, to add dynamically methods to the remotefunction you will
+		have to invoke this method once again
+		-swagner
+	 -->
+	<method name="registerMethods">
+		<![CDATA[
+			if (this.subnodes!=null){
+				var clientObj = {};
+				//Register all methods which are onstanceof netRemoteCallHib
+				for (var i=0;i<this.subnodes.length;i++){
+					//If it is of Type netRemoteCallHib then register it to the NetConnection
+					if (this.subnodes[i] instanceof lz.netRemoteCallHib){
+						clientObj[this.subnodes[i].funcname] = function( args ){
+							return canvas.thishib.remoteCallMethod(arguments.callee,arguments);
+							//return hib.remoteCallMethod(arguments.callee,args);
+						}
+					}
+				}
+				this._nc.client = clientObj;
+			}
+		]]>
+	</method>
+
+	<!--
+		Process the RemoteCall to the Right Funtion
+		-swagner
+	 -->
+	<method name="remoteCallMethod" args="callee,args">
+		<![CDATA[
+			for (var eg in this._nc){
+				if (this._nc[eg]==callee){
+					if (this.debug) {
+						//_root.Debug.write.write("DEBUG invoked a function remotely: ",eg,args);
+					}
+					if (args.length == 1) {
+						return this.callFuntion(eg,args[0]);
+					} else {
+						return this.callFuntion(eg,args);
+					}
+					//return this.callFuntion(eg,args);
+				}
+			}
+		]]>
+	</method>
+
+	<!--
+		Map the Function to a netRemoteCallHib
+		-swagner
+	 -->
+	<method name="callFuntion" args="funcname,args">
+		<![CDATA[
+			for (var i=0;i<this.subnodes.length;i++){
+				if (this.subnodes[i].funcname==funcname){
+					return this.subnodes[i].onResult(args);
+				}
+			}
+		]]>
+	</method>
+
+	<method name="callRPC" args="func, obj, params">
+		//if ($debug) Debug.write("*** call: func, obj, params",func,obj, typeof (params) ,params.length);
+		if (params.length != 0){
+			//does this really work?
+			//ASSetPropFlags(_global, null, 8, 1);
+			//setPropertyIsEnumerable(8, 1);
+			//Debug.write("does it work?",arguments);
+			<!--
+			this._nc.call.apply(this._nc,arguments);
+			 -->
 			if (params.length==1){
-			    this._nc.call(func, obj,params[0]);
+				this._nc.call(func, obj,params[0]);
 			} else if (params.length==2){
-			    this._nc.call(func, obj,params[0],params[1]);
+				this._nc.call(func, obj,params[0],params[1]);
 			} else if (params.length==3){
-			    this._nc.call(func, obj,params[0],params[1],params[2]);
+				this._nc.call(func, obj,params[0],params[1],params[2]);
 			} else if (params.length==4){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3]);
 			} else if (params.length==5){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4]);
 			} else if (params.length==6){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5]);
 			} else if (params.length==7){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6]);
 			} else if (params.length==8){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7]);
 			} else if (params.length==9){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8]);
 			} else if (params.length==10){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9]);
 			} else if (params.length==11){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10]);
 			} else if (params.length==12){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11]);
 			} else if (params.length==13){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12]);
 			} else if (params.length==14){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13]);
 			} else if (params.length==15){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14]);
 			} else if (params.length==16){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15]);
 			} else if (params.length==17){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16]);
 			} else if (params.length==18){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16],params[17]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16],params[17]);
 			} else if (params.length==19){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16],params[17],params[18]);
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16],params[17],params[18]);
 			} else if (params.length==20){
-			    this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16],params[17],params[18],params[19]);
-			}	    	 
-        } else {
-            this._nc.call(func, obj);
-        }
-    </method>
-    
+				this._nc.call(func, obj,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7],params[8],params[9],params[10],params[11],params[12],params[13],params[14],params[15],params[16],params[17],params[18],params[19]);
+			}
+		} else {
+			this._nc.call(func, obj);
+		}
+	</method>
 </class>
 
 
-    <!---
-        Net remote call. 
-        @todo Document netremotecall class.
-    -->
-    <class name="netremotecall" extends="node">
-
-        <switch>
-            <when property="$as3">
-                <passthrough>
-                    import flash.net.Responder;
-                </passthrough>
-            </when>
-        </switch>
-
-        <!--- Name of the remote function. -->
-        <attribute name="funcname" value="$once{null}" type="string" />
-    
-        <attribute name="remotecontext" value="null" />
-    
-        <attribute name="dataobject" value="null" />
-
-        <attribute name="responder" value="null" />
-		
-        <!--- Data handling event. args="value"  -->
-        <event name="ondata" />
-
-        <!--- Error handling event. -->
-        <event name="onerror"/>
-
-        <!--- Call the remote method, passing the array of params. -->
-        <method name="callRPC" args="params"><![CDATA[
-            if (this.funcname == null) {
-                //Debug.write("No funcname given");
-                if (this.onerror) this.onerror.sendEvent("No funcname given");
-                return;
-            }
-
-            if (params == null) {
-                params = new Array();
-
-                var subnodes = this.subnodes;
-                if (subnodes != null) {
-                    var i;
-                    var n = subnodes.length;
-                    for (i = 0; i < n; i++) {
-                        // If getValue method is declared in param, call that
-                        // instead to get value.
-                        var tsi = subnodes[i];
-                        //TODO: fixme
-                        //if ((tsi["getValue"] != null) && (tsi.getValue["prototype"] != null)) {
-                        //    params[i] = tsi.getValue();
-                        //    Debug.write("tsi.getValue():", tsi.getValue());
-                        //} else {
-                        //    params[i] = tsi.value;
-                        //}
-                        params[i] = tsi.getValue();
-                    }
-                }
-
-            } else if (params.__proto__ != Array.prototype) {
-                //Debug.write(this.name, "error: first argument (params) is not an array");
-                return -1;
-            }
-
-            //if ($debug) Debug.write("call", this, this.parent, this.parent.status);
-            var rtmpObject = null;
-            if (this.parent instanceof lz.rtmpConnection){
-        	    rtmpObject = this.parent;
-            } else if(this.remotecontext  instanceof lz.rtmpConnection){
-        	    rtmpObject = this.remotecontext;
-            } else {
-        	    if ($debug) Debug.warn("ERROR: no remotecontext availible abort call", this.funcname, this);
-        	    return;
-            }
-        	//Debug.write('call', this, rtmpObject, rtmpObject.status);
-        	//Debug.write('call', this.remotecontext);
-            if (rtmpObject.debug) Debug.write('call', this, rtmpObject, rtmpObject.status);
-            rtmpObject.lastCalled = this;
-
-            this.responder = new Responder(onResult);
-
-            rtmpObject.callRPC(this.funcname, this.responder, params);
-
-          ]]>
-        </method>
-
-        <!--- Handle the result returned from the remote method. -->
-        <method name="onResult" args="value"><![CDATA[
-            // Can be overriden.
-            // Would be great if it can be used with dataobject,
-            // but I don't know how to convert Array/primitive to LzDataset/LzDataPointer.
-            ////Debug.write("netremotecall", this, "onResult", value);
-
-            if (this.dataobject!=null) {
-                if ( this.dataobject instanceof LzDataset ) {
-                    //Debug.write("onResult: ",this,value,dataobject);
-                    var element = LzDataElement.valueToElement(value);
-                    this.dataobject.setData(element.childNodes);
-                } else if ( this.dataobject instanceof LzDataElement ) {
-                    var element = LzDataElement.valueToElement(value);
-                    this.dataobject.appendChild( element );
-                } else {
-                    //TODO:fixme
-                    //Debug.warn("dataobject is not LzDataset or LzDataElement: ",this,this.dataobject,delegate);
-                }
-            }
-            this.ondata.sendEvent(value);		
-          ]]>
-        </method>
-
-
-    </class>
-
-
-    <!---
-        Net parameter.
-        Element to use inside netremotecall.
-        @todo Document netparam class.
-    -->
-    <class name="netparam" extends="node">
-
-        <!--- The value of the netparam. -->
-        <attribute name="value" value="null"/>
-
-    </class>
+	<!---
+		Net remote call.
+		@todo Document netremotecall class.
+	-->
+	<class name="netremotecall" extends="node">
+		<switch>
+			<when property="$as3">
+				<passthrough>
+					import flash.net.Responder;
+				</passthrough>
+			</when>
+		</switch>
+
+		<!--- Name of the remote function. -->
+		<attribute name="funcname" value="$once{null}" type="string" />
+
+		<attribute name="remotecontext" value="null" />
+
+		<attribute name="dataobject" value="null" />
+
+		<attribute name="responder" value="null" />
+
+		<!--- Data handling event. args="value"  -->
+		<event name="ondata" />
+
+		<!--- Error handling event. -->
+		<event name="onerror"/>
+
+		<!--- Call the remote method, passing the array of params. -->
+		<method name="callRPC" args="params"><![CDATA[
+			if (this.funcname == null) {
+				//Debug.write("No funcname given");
+				if (this.onerror) this.onerror.sendEvent("No funcname given");
+				return;
+			}
+
+			if (params == null) {
+				params = new Array();
+
+				var subnodes = this.subnodes;
+				if (subnodes != null) {
+					var i;
+					var n = subnodes.length;
+					for (i = 0; i < n; i++) {
+						// If getValue method is declared in param, call that
+						// instead to get value.
+						var tsi = subnodes[i];
+						//TODO: fixme
+						//if ((tsi["getValue"] != null) && (tsi.getValue["prototype"] != null)) {
+						//	params[i] = tsi.getValue();
+						//	Debug.write("tsi.getValue():", tsi.getValue());
+						//} else {
+						//	params[i] = tsi.value;
+						//}
+						params[i] = tsi.getValue();
+					}
+				}
+
+			} else if (params.__proto__ != Array.prototype) {
+				//Debug.write(this.name, "error: first argument (params) is not an array");
+				return -1;
+			}
+
+			//if ($debug) Debug.write("call", this, this.parent, this.parent.status);
+			var rtmpObject = null;
+			if (this.parent instanceof lz.rtmpConnection){
+				rtmpObject = this.parent;
+			} else if(this.remotecontext  instanceof lz.rtmpConnection){
+				rtmpObject = this.remotecontext;
+			} else {
+				if ($debug) Debug.warn("ERROR: no remotecontext availible abort call", this.funcname, this);
+				return;
+			}
+			//Debug.write('call', this, rtmpObject, rtmpObject.status);
+			//Debug.write('call', this.remotecontext);
+			if (rtmpObject.debug) Debug.write('call', this, rtmpObject, rtmpObject.status);
+			rtmpObject.lastCalled = this;
+
+			this.responder = new Responder(onResult);
+
+			rtmpObject.callRPC(this.funcname, this.responder, params);
+
+		]]>
+		</method>
 
+		<!--- Handle the result returned from the remote method. -->
+		<method name="onResult" args="value"><![CDATA[
+			// Can be overriden.
+			// Would be great if it can be used with dataobject,
+			// but I don't know how to convert Array/primitive to LzDataset/LzDataPointer.
+			////Debug.write("netremotecall", this, "onResult", value);
+
+			if (this.dataobject!=null) {
+				if ( this.dataobject instanceof LzDataset ) {
+					//Debug.write("onResult: ",this,value,dataobject);
+					var element = LzDataElement.valueToElement(value);
+					this.dataobject.setData(element.childNodes);
+				} else if ( this.dataobject instanceof LzDataElement ) {
+					var element = LzDataElement.valueToElement(value);
+					this.dataobject.appendChild( element );
+				} else {
+					//TODO:fixme
+					//Debug.warn("dataobject is not LzDataset or LzDataElement: ",this,this.dataobject,delegate);
+				}
+			}
+			this.ondata.sendEvent(value);
+		]]>
+		</method>
+	</class>
+
+	<!---
+		Net parameter.
+		Element to use inside netremotecall.
+		@todo Document netparam class.
+	-->
+	<class name="netparam" extends="node">
+		<!--- The value of the netparam. -->
+		<attribute name="value" value="null"/>
+	</class>
 
 </library>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c79c1213/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
index d98dd4b..b8a55bf 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
@@ -18,43 +18,45 @@
  */
 package org.apache.openmeetings.web.room;
 
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_NATIVE_SSL;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_PORT;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SECURE;
+import static org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter.FLASH_SSL_PORT;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.wicket.RuntimeConfigurationType.DEVELOPMENT;
 
+import java.net.URL;
+
+import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.BasePanel;
-import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
+import org.apache.openmeetings.web.common.OmAjaxClientInfoBehavior;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
-import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
-import org.apache.wicket.protocol.http.ClientProperties;
+import org.apache.wicket.protocol.http.request.WebClientInfo;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.util.string.StringValue;
 import org.apache.wicket.util.string.Strings;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
 
 import com.github.openjson.JSONArray;
 import com.github.openjson.JSONObject;
 
 public class SwfPanel extends BasePanel {
 	private static final long serialVersionUID = 1L;
+	private final static Logger log = Red5LoggerFactory.getLogger(SwfPanel.class, webAppRootKey);
 	public static final String SWF = "swf";
 	public static final String SWF_TYPE_NETWORK = "network";
 	public static final String SWF_TYPE_SETTINGS = "settings";
 	private final PageParameters pp;
-	private final AbstractDefaultAjaxBehavior panelLoaded = new AbstractDefaultAjaxBehavior() {
-		private static final long serialVersionUID = 1L;
-
-		@Override
-		protected void respond(AjaxRequestTarget target) {
-			PageParameters spp = new PageParameters(pp);
-			target.appendJavaScript(getInitFunction(spp));
-		}
-	};
 
 	public SwfPanel(String id) {
 		this(id, new PageParameters());
@@ -68,7 +70,17 @@ public class SwfPanel extends BasePanel {
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
-		add(panelLoaded);
+		add(new OmAjaxClientInfoBehavior() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void onClientInfo(AjaxRequestTarget target, WebClientInfo info) {
+				super.onClientInfo(target, info);
+				ExtendedClientProperties cp = (ExtendedClientProperties)info.getProperties();
+				PageParameters spp = new PageParameters(pp);
+				target.appendJavaScript(getInitFunction(spp, cp));
+			}
+		});
 	}
 
 	private static ResourceReference newResourceReference() {
@@ -79,10 +91,9 @@ public class SwfPanel extends BasePanel {
 	public void renderHead(IHeaderResponse response) {
 		super.renderHead(response);
 		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(newResourceReference())));
-		response.render(OnDomReadyHeaderItem.forScript(panelLoaded.getCallbackScript()));
 	}
 
-	public String getInitFunction(PageParameters pp) {
+	public String getInitFunction(PageParameters pp, ExtendedClientProperties cp) {
 		String initStr = null;
 		StringValue type = pp.get(SWF);
 		String swf = getFlashFile(type);
@@ -110,9 +121,25 @@ public class SwfPanel extends BasePanel {
 						, "save.success");
 			}
 			JSONObject options = new JSONObject().put("src", swf + new PageParametersEncoder().encodePageParameters(pp));
-			ClientProperties cp = WebSession.get().getClientInfo().getProperties();
 			options.put("wmode", cp.isBrowserInternetExplorer() && cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct");
-			initStr = String.format("var labels = %s; initSwf(%s);", lbls, options.toString());
+
+			JSONObject s = new JSONObject();
+			try {
+				URL url = new URL(cp.getCodebase());
+				String path = url.getPath();
+				path = path.substring(1, path.indexOf('/', 2) + 1);
+				JSONObject gs = getBean(ScopeApplicationAdapter.class).getFlashSettings();
+				s.put("flashProtocol", gs.getBoolean(FLASH_SECURE) ? "rtmps" : "rtmp")
+						.put("flashPort", gs.getBoolean(FLASH_SECURE) ? gs.getString(FLASH_SSL_PORT) : gs.getString(FLASH_PORT))
+						.put("proxy", gs.getBoolean(FLASH_NATIVE_SSL) ? "best" : "none")
+						.put("httpProtocol", url.getProtocol())
+						.put("httpPort", url.getPort())
+						.put("host", url.getHost())
+						.put("path", path);
+			} catch (Exception e) {
+				log.error("Error while constructing video settings parameters", e);
+			}
+			initStr = String.format("labels = %s; config = %s; initSwf(%s);", lbls, s, options.toString());
 		}
 		return initStr;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c79c1213/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
index 0b9a08c..fad5838 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
@@ -80,7 +80,7 @@ public class VideoSettings extends Panel {
 			String path = url.getPath();
 			path = path.substring(1, path.indexOf('/', 2) + 1) + scope;
 			if (gs.getBoolean(FLASH_SECURE)) {
-				s.put(FLASH_NATIVE_SSL, gs.get(FLASH_NATIVE_SSL));
+				s.put(FLASH_NATIVE_SSL, gs.getBoolean(FLASH_NATIVE_SSL));
 				s.put(URL, getUri("rtmps", url.getHost(), gs.getString(FLASH_SSL_PORT), path));
 				s.put(FALLBACK, getUri("rtmps", url.getHost(), url.getPort(), path));
 			} else {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c79c1213/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
index 5ecc512..393ba41 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/swf-functions.js
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
+var labels, config;
 function initSwf(_options) {
 	var options = $.extend({
 		allowfullscreen : 'true',
@@ -44,6 +44,15 @@ function initSwf(_options) {
 		.attr('pluginspage', 'http://www.macromedia.com/go/getflashplayer');
 	$('#swfloading').after($('<div id="lzappContainer">').append(embed)).width('1px').height('1px');
 }
+function loadingComplete() {
+	document.getElementById("swfloading").style.display = 'none';
+	var lzApp = document.getElementById("lzappContainer");
+	lzApp.style.width = '100%';
+	lzApp.style.height = '100%';
+}
 function getStringLabels() {
 	return labels;
 }
+function getConfig() {
+	return config;
+}


[29/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] screen-sharing is displayed in room

Posted by so...@apache.org.
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
index bf8c141..64801fa 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
@@ -19,6 +19,7 @@
 package org.apache.openmeetings.web.room.menu;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.FLASH_NATIVE_SSL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSHARING_ALLOW_REMOTE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSHARING_FPS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSHARING_FPS_SHOW;
@@ -26,49 +27,38 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSH
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.WebSession.getLanguage;
-import static org.apache.openmeetings.web.room.RoomBroadcaster.getClient;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.InputStream;
-import java.net.URI;
-import java.util.Properties;
 
-import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.io.IOUtils;
 import org.apache.openmeetings.core.session.SessionManager;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room;
-import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.OmButton;
+import org.apache.openmeetings.web.room.VideoSettings;
 import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.util.resource.StringResourceStream;
-import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
+import com.github.openjson.JSONObject;
+
 public class StartSharingButton extends OmButton {
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(StartSharingButton.class, webAppRootKey);
 	private static final String CDATA_BEGIN = "<![CDATA[";
 	private static final String CDATA_END = "]]>";
 	private final AjaxDownload download;
-	private final org.apache.openmeetings.db.entity.basic.Client c;
-	private enum Protocol {
-		rtmp
-		, rtmpe
-		, rtmps
-		, rtmpt
-	}
+	private final Client c;
 
-	public StartSharingButton(String id, org.apache.openmeetings.db.entity.basic.Client c) {
+	public StartSharingButton(String id, Client c) {
 		super(id);
 		this.c = c;
 		setOutputMarkupPlaceholderTag(true);
@@ -92,25 +82,16 @@ public class StartSharingButton extends OmButton {
 			ConfigurationDao cfgDao = getBean(ConfigurationDao.class);
 			app = IOUtils.toString(jnlp, UTF_8);
 			String publicSid = c.getUid();
-			Client rc = getClient(publicSid);
-			if (rc == null || rc.getUserId() == null) {
-				throw new RuntimeException(String.format("Unable to find client by publicSID '%s'", publicSid));
-			}
-			String _url = rc.getTcUrl();
-			URI url = new URI(_url);
+			JSONObject s = VideoSettings.getInitJson(WebSession.get().getExtendedProperties(), "" + c.getRoomId(), publicSid);
+			String _url = s.getString(VideoSettings.URL);
 			long roomId = c.getRoomId();
 			Room room = getBean(RoomDao.class).get(roomId);
 			SessionManager sessionManager = getBean(SessionManager.class);
-			String path = url.getPath();
-			path = path.substring(path.lastIndexOf('/') + 1);
-			if (Strings.isEmpty(path) || rc.getRoomId() == null || !path.equals(rc.getRoomId().toString()) || !rc.getRoomId().equals(roomId)) {
-				throw new RuntimeException(String.format("Invalid room id passed %s, expected, %s", path, roomId));
-			}
-			Protocol protocol = Protocol.valueOf(url.getScheme());
-			app = addKeystore(rc, app, protocol)
+			app = app.replace("$native", "" + s.getBoolean(FLASH_NATIVE_SSL))
 					.replace("$codebase", WebSession.get().getExtendedProperties().getCodebase())
 					.replace("$applicationName", cfgDao.getAppName())
 					.replace("$url", _url)
+					.replace("$fallback", s.getString(VideoSettings.FALLBACK))
 					.replace("$publicSid", publicSid)
 					.replace("$labels", getLabels(730,  731,  732,  733,  734
 							,  735,  737,  738,  739,  740
@@ -124,7 +105,7 @@ public class StartSharingButton extends OmButton {
 					.replace("$defaultFps", cfgDao.getConfValue(CONFIG_SCREENSHARING_FPS, String.class, ""))
 					.replace("$showFps", cfgDao.getConfValue(CONFIG_SCREENSHARING_FPS_SHOW, String.class, "true"))
 					.replace("$allowRemote", cfgDao.getConfValue(CONFIG_SCREENSHARING_ALLOW_REMOTE, String.class, "true"))
-					.replace("$allowRecording", "" + (rc.getUserId() > 0 && room.isAllowRecording() && rc.isAllowRecording() && (0 == sessionManager.getRecordingCount(roomId))))
+					.replace("$allowRecording", "" + (room.isAllowRecording() && (0 == sessionManager.getRecordingCount(roomId))))
 					.replace("$allowPublishing", "" + (0 == sessionManager.getPublishingCount(roomId)))
 					;
 
@@ -151,47 +132,4 @@ public class StartSharingButton extends OmButton {
 		result.append(CDATA_END);
 		return result.toString();
 	}
-
-	private static String addKeystore(Client rc, String app, Protocol protocol) {
-		log.debug("RTMP Sharer Keystore :: start");
-		String keystore = "--dummy--", password = "--dummy--";
-		if (Protocol.rtmps == protocol) {
-			File conf = new File(OmFileHelper.getRootDir(), "conf");
-			File keyStore = new File(conf, "keystore.screen");
-			if (keyStore.exists()) {
-				try (FileInputStream fis = new FileInputStream(keyStore); FileInputStream ris = new FileInputStream(new File(conf, "red5.properties"))) {
-					Properties red5Props = new Properties();
-					red5Props.load(ris);
-
-					byte keyBytes[] = new byte[(int)keyStore.length()];
-					fis.read(keyBytes);
-
-					keystore = Hex.encodeHexString(keyBytes);
-					password = red5Props.getProperty("rtmps.screen.keystorepass");
-
-					/*
-					KeyStore ksIn = KeyStore.getInstance(KeyStore.getDefaultType());
-					ksIn.load(new FileInputStream(keyStore), red5Props.getProperty("rtmps.keystorepass").toCharArray());
-					ByteArrayInputStream bin = new ByteArrayInputStream()
-
-					byte fileContent[] = new byte[(int)file.length()];
-					sb = addArgument(sb, Object arg)
-					ctx.put("$KEYSTORE", users_id);
-					/*
-					KeyStore ksOut = KeyStore.getInstance(KeyStore.getDefaultType());
-					for (Certificate cert : ksIn.getCertificateChain("red5")) {
-						PublicKey pub = cert.getPublicKey();
-						TrustedCertificateEntry tce = new TrustedCertificateEntry(cert);
-						tce.
-					}
-					*/
-				} catch (Exception e) {
-					//no op
-				}
-			}
-		}
-		return app.replace("$native", "" + rc.isNativeSsl())
-				.replace("$keystore", CDATA_BEGIN + keystore + CDATA_END)
-				.replace("$password", CDATA_BEGIN + password + CDATA_END);
-	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index ffbfc79..2b9e9e4 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -88,24 +88,36 @@ var VideoManager = (function() {
 	function _getVid(uid) {
 		return "video" + uid;
 	}
-	function _update(o) {
-		var _id = _getVid(o.uid)
-			, video = o.activities.indexOf('broadcastV') > -1
-			, audio = o.activities.indexOf('broadcastA') > -1
+	function _update(c) {
+		var _id = _getVid(c.uid)
+			, video = c.activities.indexOf('broadcastV') > -1
+			, audio = c.activities.indexOf('broadcastA') > -1
 			, av = audio || video
 			, v = $('#' + _id);
-		if (av && v.length != 1) {
-			Video().init(box, o);
+		if (av && v.length != 1 && !!c.self) {
+			Video().init(box, c);
 		} else if (av && v.length == 1) {
-			v.data().update(o);
+			v.data().update(c);
 		} else if (!av && v.length == 1) {
 			v.remove();
 		}
 	}
+	function _play(c) {
+		Video().init(box, c);
+	}
+	function _close(uid) {
+		var _id = _getVid(uid)
+			, v = $('#' + _id);
+		if (v.length == 1) {
+			v.remove();
+		}
+	}
 
 	self.getOptions = function() { return JSON.parse(JSON.stringify(options)); };
 	self.init = _init;
 	self.update = _update;
+	self.play = _play;
+	self.close = _close;
 	self.resetSize = function(uid) { $('#' + _getVid(uid)).data().resetSize(); };
 	return self;
 })();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index 62aaf2d..168bea9 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -27,7 +27,7 @@ import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.basic.Client.Pod;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e7bab5bc/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
index a4ade15..dce1914 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -45,7 +45,7 @@
 	<context:component-scan base-package="org.apache.openmeetings" />
 
 	<!-- New Class for the Streaming Handlers -->
-	<bean id="web.handler" class="org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter" />
+	<bean id="web.handler" class="org.apache.openmeetings.core.remote.ScopeApplicationAdapter" />
 
 	<!-- Session configuration start -->
 


[12/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] basic save is added, code clean-up

Posted by so...@apache.org.
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index ec7ad9a..d2da4dd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -119,6 +119,7 @@ var APointer = function(wb) {
 			function go(_cnt) {
 				if (_cnt < 0) {
 					canvas.remove(group);
+					return;
 				}
 				circle1.set({radius: 3});
 				circle2.set({radius: 6});
@@ -550,6 +551,7 @@ var Wb = function() {
 				}
 			]
 		});
+		return confirm;
 	}
 	function internalInit() {
 		t.draggable({
@@ -587,6 +589,9 @@ var Wb = function() {
 			t.find('.om-icon.clear-slide').click(function() {
 				confirmDlg('clear-slide-confirm', function() { wbAction('clearSlide', JSON.stringify({wbId: wb.id, slide: slide})); });
 			});
+			t.find('.om-icon.save').click(function() {
+				wbAction('save', JSON.stringify({wbId: wb.id}));
+			});
 			s.find('.wb-prop-b, .wb-prop-i')
 				.button()
 				.click(function() {
@@ -1140,7 +1145,7 @@ var WbArea = (function() {
 				return res;
 			}
 			, activate: function(e, ui) {
-				wbAction('activeWb', JSON.stringify({id: ui.newTab.data('wb-id')}));
+				wbAction('activateWb', JSON.stringify({id: ui.newTab.data('wb-id')}));
 			}
 		});
 		scroll = tabs.find('.scroll-container');
@@ -1171,11 +1176,11 @@ var WbArea = (function() {
 		wbo.init(obj.id, tid, readOnly);
 		_resizeWbs();
 	}
-	self.add = function(obj) {
+	self.createWb = function(obj) {
 		self.create(obj);
 		_activateTab(obj.id);
 	};
-	self.activate = function(obj) {
+	self.activateWb = function(obj) {
 		_activateTab(obj.id);
 	}
 	self.load = function(json) {
@@ -1190,7 +1195,7 @@ var WbArea = (function() {
 	self.modifyObj = function(json) {
 		self.getWb(json.wbId).modifyObj(json.obj);
 	};
-	self.removeObj = function(json) {
+	self.deleteObj = function(json) {
 		self.getWb(json.wbId).removeObj(json.obj);
 	};
 	self.clearAll = function(json) {
@@ -1200,7 +1205,7 @@ var WbArea = (function() {
 	self.clearSlide = function(json) {
 		self.getWb(json.wbId).clearSlide(json.slide);
 	};
-	self.remove = function(obj) {
+	self.removeWb = function(obj) {
 		var tabId = self.getWbTabId(obj.id);
 		tabs.find('li[aria-controls="' + tabId + '"]').remove();
 		$("#" + tabId).remove();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
index bc68354..89a8a98 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
@@ -44,7 +44,7 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.UserContact;
 import org.apache.openmeetings.web.admin.SearchableDataView;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.common.AddFolderDialog;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.PagedEntityListPanel;
 import org.apache.openmeetings.web.common.UserPanel;
@@ -265,7 +265,7 @@ public class MessagesContactsPanel extends UserPanel {
 		foldersModel.setObject(getBean(PrivateMessageFolderDao.class).get(0, Integer.MAX_VALUE));
 		updateMoveModel();
 
-		final AddFolderDialog addFolder = new AddFolderDialog("addFolder") {
+		final NameDialog addFolder = new NameDialog("addFolder") {
 			private static final long serialVersionUID = 1L;
 
 			@Override

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
index 9b3192c..4026398 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
@@ -26,7 +26,7 @@ import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.dto.record.RecordingContainerData;
 import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.common.AddFolderDialog;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.UserPanel;
 import org.apache.openmeetings.web.common.tree.FileTreePanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -35,7 +35,7 @@ public class RecordingsPanel extends UserPanel {
 	private static final long serialVersionUID = 1L;
 	private final VideoPlayer video = new VideoPlayer("video");
 	private final VideoInfo info = new VideoInfo("info");
-	private final AddFolderDialog addFolder = new AddFolderDialog("addFolder", Application.getString(712)) {
+	private final NameDialog addFolder = new NameDialog("addFolder", Application.getString(712)) {
 		private static final long serialVersionUID = 1L;
 
 		@Override

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/web.xml b/openmeetings-web/src/main/webapp/WEB-INF/web.xml
index 76b78d7..973ef1c 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/web.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/web.xml
@@ -7,20 +7,20 @@
   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.
-  
+
 -->
-<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
 	<context-param>
 		<param-name>globalScope</param-name>
 		<param-value>default</param-value>


[26/50] [abbrv] openmeetings git commit: Code is updated according to latest wicket changes

Posted by so...@apache.org.
Code is updated according to latest wicket changes


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/e227dd4c
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/e227dd4c
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/e227dd4c

Branch: refs/heads/master
Commit: e227dd4c13d7ba034738affa4847e330d67597b6
Parents: b1c6009
Author: Maxim Solodovnik <so...@apache.org>
Authored: Thu Apr 13 01:23:25 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Thu Apr 13 01:23:25 2017 +0000

----------------------------------------------------------------------
 .../src/site/xdoc/red5sip-integration_4.0.xml   | 304 +++++++++++++++++++
 .../web/util/FileItemResourceReference.java     |   2 +-
 .../web/util/GroupLogoResourceReference.java    |   6 +-
 3 files changed, 308 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e227dd4c/openmeetings-server/src/site/xdoc/red5sip-integration_4.0.xml
----------------------------------------------------------------------
diff --git a/openmeetings-server/src/site/xdoc/red5sip-integration_4.0.xml b/openmeetings-server/src/site/xdoc/red5sip-integration_4.0.xml
new file mode 100644
index 0000000..fb9b7f0
--- /dev/null
+++ b/openmeetings-server/src/site/xdoc/red5sip-integration_4.0.xml
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed 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.
+ -->
+<document xmlns="http://maven.apache.org/XDOC/2.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>SIP-Transport Integration</title>
+		<author email="dev@openmeetings.apache.org">Apache OpenMeetings Team</author>
+	</properties>
+	<body>
+		<section name="SIP-Transport Integration">
+			<p>You need Apache OpenMeetings <strong>version 3.1+</strong> to apply this guide!</p>
+			<p>You need Asterisk <strong>version 13+</strong> to apply this guide!</p>
+			<p>Here is instruction how-to set up red5sip transport integration with OpenMeetings on Ubuntu 12.10.</p>
+		</section>
+		<section name="Prerequisites">
+			<div>
+				Run the commands
+				<source>
+<![CDATA[
+sudo apt-get update && sudo apt-get upgrade
+]]>
+				</source>
+			</div>
+		</section>
+		<section name="Building and setting up Asterisk">
+			<div>
+				Run the commands
+				<source>
+<![CDATA[
+sudo mkdir /usr/src/asterisk &amp;&amp; cd /usr/src/asterisk
+sudo wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-13.9.0.tar.gz
+sudo tar -xvzf asterisk-13.9.0.tar.gz
+cd ./asterisk-13.9.0
+sudo make clean
+sudo contrib/scripts/install_prereq install
+sudo ./configure
+sudo make menuconfig
+]]>
+				</source>
+				Make sure you have selected  <tt>Add-ons -> res_config_mysql</tt>, Press F12 to save
+				<source>
+<![CDATA[
+sudo make
+sudo make install
+sudo make samples
+sudo make config
+sudo service asterisk start
+]]>
+				</source>
+			</div>
+		</section>
+		<section name="Configure Asterisk">
+			<div>
+				Enable asterisk MySQL module:<br /><br />
+				Modify "[modules]" section of <tt>/etc/asterisk/modules.conf</tt> as follows:<br />
+				<strong>Add/uncomment the following lines</strong>
+				<source>
+<![CDATA[
+preload => res_config_mysql.so
+]]>
+				</source>
+			</div><br />
+			<div>
+				Configure MySQL module:<br /><br />
+				Set valid data for MySQL in <tt>/etc/asterisk/res_config_mysql.conf</tt> :<br />
+				<strong>Example</strong>
+				<source>
+<![CDATA[
+[general]
+dbhost = 127.0.0.1
+dbname = openmeetings
+dbuser = root
+dbpass =
+dbport = 3306
+dbsock = /var/lib/mysql/mysql.sock
+dbcharset = utf8
+requirements=warn
+]]>
+				</source>
+			</div><br />
+			<div>
+				Modify <tt>/etc/asterisk/sip.conf</tt><br />
+				<strong>Add/uncomment the following line</strong>:<br />
+				<source>
+<![CDATA[
+videosupport=yes
+rtcachefriends=yes
+]]>
+				</source>
+				<strong>Increase maxexpiry value to 43200</strong>:<br />
+				<source>
+<![CDATA[
+maxexpiry=43200
+]]>
+				</source>
+				<strong>Add user for the "SIP Transport"</strong>:<br />
+				<source>
+<![CDATA[
+[red5sip_user]
+type=friend
+secret=12345
+disallow=all
+allow=ulaw
+allow=h263
+host=dynamic
+nat=force_rport,comedia
+context=rooms-red5sip
+]]>
+				</source>
+			</div><br />
+			<div>
+				Add next lines into the <tt>/etc/asterisk/extconfig.conf</tt>:
+				<source>
+<![CDATA[
+[settings]
+sippeers => mysql,general,sipusers
+]]>
+				</source>
+			</div><br />
+			<div>
+				Modify <tt>/etc/asterisk/extensions.conf</tt><br />
+				<strong>Add the following section</strong>:<br />
+				<source>
+<![CDATA[
+; *****************************************************
+; The below dial plan is used to dial into a Openmeetings Conference room
+; The first line DB_EXISTS(openmeetings/room/ does not belong to the openmeetings application but is the name of astDB containing the astDB family/key pair and values
+; To Check if your astDB has been created do the following in a terminal window type the following:
+; asterisk \u2013rx \u201cdatabase show\u201d
+; If you do not receive an output with that resembles openmeetings/rooms/400## where \u201c##\u201d will equal the extension assigned when you created your room
+; If you do not receive the above output check your parameters in /opt/red5/webapps/openmeetings/WEB-INF/classes/applicationContext.xml
+; Go back into the Administrator Panel and remove the PIN number in each room save the record with no PIN number and then re-enter the pin again resave the record.
+; *****************************************************
+
+[rooms]
+exten => _400X!,1,GotoIf($[${DB_EXISTS(openmeetings/rooms/${EXTEN})}]?ok:notavail)
+exten => _400X!,n(ok),SET(PIN=${DB(openmeetings/rooms/${EXTEN})})
+exten => _400X!,n,Set(CONFBRIDGE(user,template)=sip_user)
+exten => _400X!,n,Set(CONFBRIDGE(user,pin)=${PIN})
+exten => _400X!,n(ok),Confbridge(${EXTEN},default_bridge,)
+exten => _400X!,n,Hangup
+exten => _400X!,n(notavail),Answer()
+exten => _400X!,n,Playback(invalid)
+exten => _400X!,n,Hangup
+
+[rooms-originate]
+exten => _400X!,1,Confbridge(${EXTEN},default_bridge,sip_user)
+exten => _400X!,n,Hangup
+
+[rooms-out]
+; *****************************************************
+; Extensions for outgoing calls from Openmeetings room.
+; *****************************************************
+
+[rooms-red5sip]
+exten => _400X!,1,GotoIf($[${DB_EXISTS(openmeetings/rooms/${EXTEN})}]?ok:notavail)
+exten => _400X!,n(ok),Confbridge(${EXTEN},default_bridge,red5sip_user)
+exten => _400X!,n(notavail),Hangup
+]]>
+				</source>
+			</div><br />
+			<div>
+				Modify <tt>/etc/asterisk/confbridge.conf</tt><br />
+				<strong>Add/Modify the following secions</strong>:<br />
+				<source>
+<![CDATA[
+[general]
+
+[red5sip_user]
+type=user
+marked=yes
+dsp_drop_silence=yes
+denoise=true
+
+[sip_user]
+type=user
+end_marked=yes
+wait_marked=yes
+music_on_hold_when_empty=yes
+dsp_drop_silence=yes
+denoise=true
+
+[default_bridge]
+type=bridge
+video_mode=follow_talker 
+]]>
+				</source>
+			</div><br />
+			<div>
+				To enable Asterisk Manager API modify <tt>/etc/asterisk/manager.conf</tt><br />
+				<strong>Add/Modify the following sections</strong>:<br />
+				<source>
+<![CDATA[
+[general]
+enabled = yes
+webenabled = no
+port = 5038
+bindaddr = 127.0.0.1
+
+[openmeetings]
+secret = 12345
+deny=0.0.0.0/0.0.0.0
+permit=127.0.0.1/255.255.255.0
+read = all
+write = all
+]]>
+				</source>
+			</div><br />
+			<div>
+				Update OpenMeetings with credentials for Asterisk manager. 
+				Modify <tt>/opt/red5/webapps/openmeetings/WEB-INF/classes/applicationContext.xml</tt><br />
+				find <strong>&lt;bean id="sipDao" class="org.apache.openmeetings.db.dao.room.SipDao"&gt;</strong>
+				uncomment its parameters and set it to your custom values.
+				<p style="font-size: larger; color: blue;">
+					IMPORTANT: this step should be done <strong>BEFORE</strong> system install/restore
+					otherwise all SIP related room information will be lost
+				</p>   
+			</div><br />
+			<div>
+				Restart asterisk:
+				<source>
+<![CDATA[
+service asterisk restart
+]]>
+				</source>
+			</div><br />
+		</section>
+
+		<section name="Setup red5sip transport">
+			<ul>
+				<li>Download red5sip from <tt>https://github.com/openmeetings/red5sip</tt>
+					<source>
+<![CDATA[
+git clone https://github.com/openmeetings/red5sip.git
+]]>
+					</source>
+				</li>
+				<li>Build with Apache Maven
+					<source>
+<![CDATA[
+cd red5sip
+mvn clean package
+]]>
+					</source>
+				</li>
+				<li>All necessary files will be available in <tt>target</tt> folder, copy/move it to /opt/red5sip/</li>
+				<li>Insert proper values to the <tt>/opt/red5sip/settings.properties</tt>
+					<source>
+<![CDATA[
+red5.host=127.0.0.1 # red5 server address
+om.context=openmeetings # Openmeetings context 
+red5.codec=asao
+red5.codec.rate=22 # should correlate with mic settings in public/config.xml
+sip.obproxy=127.0.0.1 # asterisk adderss
+sip.phone=red5sip_user # sip phone number
+sip.authid=red5sip_user # sip auth id
+sip.secret=12345 # sip password
+sip.realm=asterisk # sip realm
+sip.proxy=127.0.0.1 # address of sip proxy
+rooms.forceStart=no # TBD
+rooms=1 # TBD (not in use)
+]]>
+					</source>
+				</li>
+				<li>Add red5sip to autostart:
+					<source>
+<![CDATA[
+sudo cp /opt/red5sip/red5sip /etc/init.d/
+sudo chmod a+x /etc/init.d/red5sip
+sudo update-rc.d red5sip defaults
+]]>
+					</source>
+				</li>
+				<li>Start openmeetings
+					<source>
+<![CDATA[
+service red5 start
+]]>
+					</source>
+				</li>
+				<li>Start red5sip
+					<source>
+<![CDATA[
+service red5sip start
+]]>
+					</source>
+				</li>
+			</ul>
+		</section>
+	</body>
+</document>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e227dd4c/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/FileItemResourceReference.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/FileItemResourceReference.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/FileItemResourceReference.java
index d2f5ac0..7082563 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/FileItemResourceReference.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/FileItemResourceReference.java
@@ -58,7 +58,7 @@ public abstract class FileItemResourceReference<T extends FileItem> extends File
 				r = getFileItem(attr);
 				if (r != null) {
 					file = getFile(r, attr);
-					ResourceResponse rr = createResourceResponse(file.toPath());
+					ResourceResponse rr = createResourceResponse(attr, file.toPath());
 					rr.setFileName(getFileName(r));
 					return rr;
 				} else {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/e227dd4c/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/GroupLogoResourceReference.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/GroupLogoResourceReference.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/GroupLogoResourceReference.java
index a022e6e..c79c867 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/GroupLogoResourceReference.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/GroupLogoResourceReference.java
@@ -49,8 +49,8 @@ public class GroupLogoResourceReference extends FileSystemResourceReference {
 			}
 
 			@Override
-			protected ResourceResponse newResourceResponse(Attributes attributes) {
-				PageParameters params = attributes.getParameters();
+			protected ResourceResponse newResourceResponse(Attributes attrs) {
+				PageParameters params = attrs.getParameters();
 				StringValue _id = params.get("id");
 				Long id = null;
 				try {
@@ -58,7 +58,7 @@ public class GroupLogoResourceReference extends FileSystemResourceReference {
 				} catch (Exception e) {
 					//no-op expected
 				}
-				return createResourceResponse(getGroupLogo(id, true).toPath());
+				return createResourceResponse(attrs, getGroupLogo(id, true).toPath());
 			}
 		};
 	}


[15/50] [abbrv] openmeetings git commit: Changelog is updated to have changes for all versions

Posted by so...@apache.org.
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/d8a5a807/CHANGELOG
----------------------------------------------------------------------
diff --git a/CHANGELOG b/CHANGELOG
index 54f707d..f8cebf7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -59,3 +59,1481 @@ Release Notes - Openmeetings - Version 3.2.1
 
 ** New Feature
     * [OPENMEETINGS-573] - Audio notification for new chat message
+
+
+Release Notes - Openmeetings - Version 3.2.0
+================================================================================================================
+** Sub-task
+    * [OPENMEETINGS-896] - Basic room layout should be created
+    * [OPENMEETINGS-1030] - Add Files section
+    * [OPENMEETINGS-1045] - Screen-sharing button/action should be added
+    * [OPENMEETINGS-1085] - Room Rights should be implemented
+    * [OPENMEETINGS-1120] - Activities section should be added
+    * [OPENMEETINGS-1376] - User list should be fully implemented
+    * [OPENMEETINGS-1386] - CalDAV client prerequisites
+    * [OPENMEETINGS-1391] - Fix CalDAV4j issues
+    * [OPENMEETINGS-1392] - Implement OM CalDAV client
+    * [OPENMEETINGS-1454] - Interview room should work as expected
+    * [OPENMEETINGS-1455] - invitationHash/securityHash should work
+    * [OPENMEETINGS-1458] - Show nickname dialog should be added
+    * [OPENMEETINGS-1459] - External users need to be redirected on connection error
+    * [OPENMEETINGS-1469] - Download functionality is missing in file tree
+
+** Bug
+    * [OPENMEETINGS-508] - Network testing page is not localized
+    * [OPENMEETINGS-653] - playing video follow the scrolling of the screen and leave its player.
+    * [OPENMEETINGS-827] - Video play/stop event acceptable one time in all tab
+    * [OPENMEETINGS-840] - Strange uploaded video behaviour 
+    * [OPENMEETINGS-863] - Video Problem
+    * [OPENMEETINGS-1327] - Messages are being displayed in the folder right after creation
+    * [OPENMEETINGS-1358] - RTMPS SSHHandshakeFailed error  in 3.0.7 and working fine with 3.0.4
+    * [OPENMEETINGS-1377] - Backup fails when appointment has deleted room
+    * [OPENMEETINGS-1379] - XSS in Chat window leading to DOS
+    * [OPENMEETINGS-1380] - Chat messages are not being imported
+    * [OPENMEETINGS-1384] - SIP dial to room need to be fixed
+    * [OPENMEETINGS-1385] - Moving Uploaded Images
+    * [OPENMEETINGS-1396] - Swf selection should be improved
+    * [OPENMEETINGS-1399] - OpenMeetings is vulnerable to session fixation
+    * [OPENMEETINGS-1400] - Admin>Conference Rooms>Appointment Room Checkbox
+    * [OPENMEETINGS-1401] - Email Reminders for Calendared Events Not Issued
+    * [OPENMEETINGS-1402] - Screen Sharing issue with Greek language
+    * [OPENMEETINGS-1406] - View profile form is broken
+    * [OPENMEETINGS-1410] - Om failed to install using Oracle
+    * [OPENMEETINGS-1411] - allowSameURLMultipleTimes parameter for secure hash is broken
+    * [OPENMEETINGS-1412] - Window too big when changing resolution in Audio-Video Recording Test Application
+    * [OPENMEETINGS-1414] - spring-mvc and batik need to be removed
+    * [OPENMEETINGS-1416] - Users with moderator's flag in usergroup do not become moderators in rooms.
+    * [OPENMEETINGS-1417] - Check/uncheck of moderator flag in usergroups doesn't work.
+    * [OPENMEETINGS-1422] - WB is not usable for the appointment room
+    * [OPENMEETINGS-1423] - Aspect ration is being changed for WB video
+    * [OPENMEETINGS-1432] - Recording download from Moodle is broken
+    * [OPENMEETINGS-1433] - WB vertical tools panel is broken
+    * [OPENMEETINGS-1434] - Only the first group is added in ATTRIBUTE mode
+    * [OPENMEETINGS-1435] - Whiteboard Pointer in OM-3.1.2 gives wrong user name
+    * [OPENMEETINGS-1438] - Recordings permission check is broken
+    * [OPENMEETINGS-1442] - Remote keyboard is not working in screen-sharing app
+    * [OPENMEETINGS-1443] - Invitations are broken
+    * [OPENMEETINGS-1444] - Language editor is broken
+    * [OPENMEETINGS-1448] - Recordings backup fails "Enum missing"
+    * [OPENMEETINGS-1449] - Check box "Do not ask again" in "Choose device" dialog doesn't work
+    * [OPENMEETINGS-1451] - SOAP/REST API documentation need to be improved
+    * [OPENMEETINGS-1457] - flvRecordings and fileExplorerItem::Video file name depends on id
+    * [OPENMEETINGS-1460] - Application.ONLINE_USERS does not reflect changes to Client instances
+    * [OPENMEETINGS-1461] - We need to switch to java8
+    * [OPENMEETINGS-1464] - Clear objects on current slide only is not working
+    * [OPENMEETINGS-1465] - Password field is enabled when Password protected is not checked
+    * [OPENMEETINGS-1466] - REST/SOAP methods are incomplete
+    * [OPENMEETINGS-1468] - problems with keyborad usage while screensharing with remote desktop 
+    * [OPENMEETINGS-1470] - WB video is not displayed
+    * [OPENMEETINGS-1472] - User cannot be deleted
+    * [OPENMEETINGS-1476] - Deleted records are shown under trash
+    * [OPENMEETINGS-1478] - Admin->Connections displays outdated connections
+    * [OPENMEETINGS-1479] - Dashboard Chat not disabled when dashboard.show.chat value is 0
+    * [OPENMEETINGS-1482] - Om performance issues
+    * [OPENMEETINGS-1483] - Error while installing OM on MSSQL
+    * [OPENMEETINGS-1486] - Registration dialog is broken
+    * [OPENMEETINGS-1487] - Clear text passwords shouldn't be sent via email
+    * [OPENMEETINGS-1489] - Calendar in broken in French
+    * [OPENMEETINGS-1492] - OM 3.1.3 duplication records in database
+    * [OPENMEETINGS-1494] - Calendar & Events
+    * [OPENMEETINGS-1495] - Labels in admin forms are overlapping with inputs
+    * [OPENMEETINGS-1496] - Dates from backup files are being parsed with errors
+    * [OPENMEETINGS-1498] - Exception is thown when user exit from the room
+    * [OPENMEETINGS-1499] - Backup import is crached under OS Windows
+    * [OPENMEETINGS-1500] - Image drop is broken, in case "don't ask" is selected
+    * [OPENMEETINGS-1502] - NullPointerException while checking existing LDAP user
+    * [OPENMEETINGS-1504] - User with no password is being created in Web installer
+    * [OPENMEETINGS-1505] - Password is not checked when owner invite guest to the room with password protected invitation
+    * [OPENMEETINGS-1508] - Italian translation
+    * [OPENMEETINGS-1509] - Count of users in the room on the rooms page is not updated when any user exit from room
+    * [OPENMEETINGS-1510] - WB drawing should be more smooth
+    * [OPENMEETINGS-1511] - LDAP user profile picture
+    * [OPENMEETINGS-1513] - The Installer Converters page should be improved
+    * [OPENMEETINGS-1518] - Recorgings should not be converted to ogg/avi format
+    * [OPENMEETINGS-1521] - 'null' is shown instead of usergroup when user update and save User details
+    * [OPENMEETINGS-1524] - Poll description is missed in the Poll results
+    * [OPENMEETINGS-1525] - Openmeetings 3.1.3 - Problem with script red5-highperf.sh 
+    * [OPENMEETINGS-1532] - Recording folders not always imported as expected
+    * [OPENMEETINGS-1533] - Impossible to create Appointment using calendar WebService
+    * [OPENMEETINGS-1534] - Video upload to room is broken
+    * [OPENMEETINGS-1535] - Calendar web service range method is broken
+    * [OPENMEETINGS-1537] - external soap users unable to login to the conference room created
+    * [OPENMEETINGS-1539] - Calendar web service: delete method returns nothing on success
+    * [OPENMEETINGS-1540] - Placeholder in reset template email is not being replaced
+    * [OPENMEETINGS-1541] - Appointment invitations are not always accessible
+    * [OPENMEETINGS-1542] - Ajax busy status is not displayed in the room
+    * [OPENMEETINGS-1543] - Webservice Calendar/range
+    * [OPENMEETINGS-1545] - Screen-sharing is broken
+    * [OPENMEETINGS-1546] - Secure hash is not working every other time
+    * [OPENMEETINGS-1548] - EmoticonsBehavior should be removed to speed up OM in FF
+    * [OPENMEETINGS-1549] - Command line admin fails to install
+
+** Improvement
+    * [OPENMEETINGS-652] - video playback is not very clear and there isn't a pause button.
+    * [OPENMEETINGS-1138] - In the general interface, provide a way to access links to recordings, which can be shared with others (both registered users and external people).
+    * [OPENMEETINGS-1366] - Recommendations
+    * [OPENMEETINGS-1373] - 3.2.0 Library versions should be updated
+    * [OPENMEETINGS-1382] - Update default avatar of user 
+    * [OPENMEETINGS-1383] - Updated French translation for OpenMeetings 3.1.1/3.1.1+
+    * [OPENMEETINGS-1393] - Missing text strings are not internationalized for translation
+    * [OPENMEETINGS-1403] - External cameras should be supported
+    * [OPENMEETINGS-1405] - Appointment dialog should be simplified
+    * [OPENMEETINGS-1419] - Connect to Oracle DB with Service Name through Web Installer
+    * [OPENMEETINGS-1445] - 3.1.2 Build Compilation Warnings
+    * [OPENMEETINGS-1446] - SSL installation not fully working
+    * [OPENMEETINGS-1462] - Implementation for a delete button for the chat content on the principal chat window 
+    * [OPENMEETINGS-1480] - Ukrainian translation need to be improved
+    * [OPENMEETINGS-1488] - Additional functionality for groups
+    * [OPENMEETINGS-1490] - Jodconverter should be added to openmeetings project
+    * [OPENMEETINGS-1507] - Remove "application.base.url" configuration key
+    * [OPENMEETINGS-1512] - Wrong LDAP value can cause error on My Profile Page
+    * [OPENMEETINGS-1527] - Multiselect using Shift/Ctrl need to be added to file tree
+
+** New Feature
+    * [OPENMEETINGS-895] - HTML5 room should be implemented
+    * [OPENMEETINGS-1408] - provide device-settings dialog via link
+    * [OPENMEETINGS-1427] - Re-name Witheboards tabs
+    * [OPENMEETINGS-1453] - Provision for getting OpenMeetings version from SOAP/REST api
+    * [OPENMEETINGS-1501] - Openmeetings - deleting emails
+
+** Task
+    * [OPENMEETINGS-1515] - Fluido skin for the site should be replaced with reflow
+
+** Test
+    * [OPENMEETINGS-1516] - Users are kicked off the rooms and participant list is incomplete
+
+** Wish
+    * [OPENMEETINGS-853] - temporary uploaded files
+
+
+Release Notes - Openmeetings - Version 3.1.5
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-863] - Video Problem
+    * [OPENMEETINGS-1401] - Email Reminders for Calendared Events Not Issued
+    * [OPENMEETINGS-1530] - Secure Hash is broken
+    * [OPENMEETINGS-1532] - Recording folders not always imported as expected
+    * [OPENMEETINGS-1533] - Impossible to create Appointment using calendar WebService
+    * [OPENMEETINGS-1535] - Calendar web service range method is broken
+    * [OPENMEETINGS-1537] - external soap users unable to login to the conference room created
+    * [OPENMEETINGS-1539] - Calendar web service: delete method returns nothing on success
+    * [OPENMEETINGS-1540] - Placeholder in reset template email is not being replaced
+    * [OPENMEETINGS-1541] - Appointment invitations are not always accessible
+
+** Improvement
+    * [OPENMEETINGS-1531] - 3.1.5 - Library versions should be updated
+
+
+Release Notes - Openmeetings - Version 3.1.4
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-827] - Video play/stop event acceptable one time in all tab
+    * [OPENMEETINGS-1451] - SOAP/REST API documentation need to be improved
+    * [OPENMEETINGS-1475] - Select area is not unattached from cursor
+    * [OPENMEETINGS-1476] - Deleted records are shown under trash
+    * [OPENMEETINGS-1478] - Admin->Connections displays outdated connections
+    * [OPENMEETINGS-1479] - Dashboard Chat not disabled when dashboard.show.chat value is 0
+    * [OPENMEETINGS-1482] - Om performance issues
+    * [OPENMEETINGS-1483] - Error while installing OM on MSSQL
+    * [OPENMEETINGS-1484] - Super moderator is not moderator
+    * [OPENMEETINGS-1485] - Scroll is broken in restricted room
+    * [OPENMEETINGS-1486] - Registration dialog is broken
+    * [OPENMEETINGS-1487] - Clear text passwords shouldn't be sent via email
+    * [OPENMEETINGS-1489] - Calendar in broken in French
+    * [OPENMEETINGS-1492] - OM 3.1.3 duplication records in database
+    * [OPENMEETINGS-1494] - Calendar & Events
+    * [OPENMEETINGS-1495] - Labels in admin forms are overlapping with inputs
+    * [OPENMEETINGS-1496] - Dates from backup files are being parsed with errors
+    * [OPENMEETINGS-1499] - Backup import is crached under OS Windows
+    * [OPENMEETINGS-1500] - Image drop is broken, in case "don't ask" is selected
+    * [OPENMEETINGS-1502] - NullPointerException while checking existing LDAP user
+    * [OPENMEETINGS-1503] - WML file (saved WB) cannot be loaded - file not found
+    * [OPENMEETINGS-1504] - User with no password is being created in Web installer
+    * [OPENMEETINGS-1508] - Italian translation
+    * [OPENMEETINGS-1510] - WB drawing should be more smooth
+    * [OPENMEETINGS-1511] - LDAP user profile picture
+    * [OPENMEETINGS-1513] - The Installer Converters page should be improved
+    * [OPENMEETINGS-1514] - No show whiteboard after send invitation-meeting from Calendar
+    * [OPENMEETINGS-1517] - Close private chat is broken
+    * [OPENMEETINGS-1518] - Recorgings should not be converted to ogg/avi format
+    * [OPENMEETINGS-1521] - 'null' is shown instead of usergroup when user update and save User details
+    * [OPENMEETINGS-1523] - Inplace folder rename is not working
+    * [OPENMEETINGS-1524] - Poll description is missed in the Poll results
+    * [OPENMEETINGS-1525] - Openmeetings 3.1.3 - Problem with script red5-highperf.sh 
+
+** Improvement
+    * [OPENMEETINGS-1366] - Recommendations
+    * [OPENMEETINGS-1462] - Implementation for a delete button for the chat content on the principal chat window 
+    * [OPENMEETINGS-1467] - 3.1.4 Library versions should be updated
+    * [OPENMEETINGS-1480] - Ukrainian translation need to be improved
+    * [OPENMEETINGS-1488] - Additional functionality for groups
+    * [OPENMEETINGS-1490] - Jodconverter should be added to openmeetings project
+    * [OPENMEETINGS-1507] - Remove "application.base.url" configuration key
+    * [OPENMEETINGS-1512] - Wrong LDAP value can cause error on My Profile Page
+    * [OPENMEETINGS-1526] - Multiselect using Shift/Ctrl need to be added to file tree
+
+** New Feature
+    * [OPENMEETINGS-1427] - Re-name Witheboards tabs
+    * [OPENMEETINGS-1477] - Default chat font is too small
+    * [OPENMEETINGS-1501] - Openmeetings - deleting emails
+
+** Task
+    * [OPENMEETINGS-1515] - Fluido skin for the site should be replaced with reflow
+
+** Test
+    * [OPENMEETINGS-1516] - Users are kicked off the rooms and participant list is incomplete
+
+
+Release Notes - Openmeetings - Version 3.1.3
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-508] - Network testing page is not localized
+    * [OPENMEETINGS-1267] - inproper handover of rtmphostlocal to screenshare-client
+    * [OPENMEETINGS-1358] - RTMPS SSHHandshakeFailed error  in 3.0.7 and working fine with 3.0.4
+    * [OPENMEETINGS-1448] - Recordings backup fails "Enum missing"
+    * [OPENMEETINGS-1460] - Application.ONLINE_USERS does not reflect changes to Client instances
+    * [OPENMEETINGS-1461] - We need to switch to java8
+    * [OPENMEETINGS-1464] - Clear objects on current slide only is not working
+    * [OPENMEETINGS-1465] - Password field is enabled when Password protected is not checked
+    * [OPENMEETINGS-1466] - REST/SOAP methods are incomplete
+    * [OPENMEETINGS-1468] - problems with keyborad usage while screensharing with remote desktop 
+    * [OPENMEETINGS-1470] - WB video is not displayed
+    * [OPENMEETINGS-1472] - User cannot be deleted
+    * [OPENMEETINGS-1473] - JPG file display in the room is broken
+    * [OPENMEETINGS-1474] - Users are not being displayed in restricted room
+
+** Improvement
+    * [OPENMEETINGS-652] - video playback is not very clear and there isn't a pause button.
+    * [OPENMEETINGS-1138] - In the general interface, provide a way to access links to recordings, which can be shared with others (both registered users and external people).
+    * [OPENMEETINGS-1445] - 3.1.2 Build Compilation Warnings
+    * [OPENMEETINGS-1446] - SSL installation not fully working
+    * [OPENMEETINGS-1447] - 3.1.3 - Library versions should be updated
+
+** New Feature
+    * [OPENMEETINGS-1408] - provide device-settings dialog via link
+    * [OPENMEETINGS-1453] - Provision for getting OpenMeetings version from SOAP/REST api
+
+
+Release Notes - Openmeetings - Version 3.1.2
+================================================================================================================
+** Vulnerability
+    * CVE-2016-3089 - Apache Openmeetings XSS in SWF panel
+
+** Bug
+    * [OPENMEETINGS-412] - Spacebar and enter key cause keyboard remote control to fail while screen sharing
+    * [OPENMEETINGS-653] - playing video follow the scrolling of the screen and leave its player.
+    * [OPENMEETINGS-1319] - Flash player crashes
+    * [OPENMEETINGS-1327] - Messages are being displayed in the folder right after creation
+    * [OPENMEETINGS-1330] - Contact being deleted from contact list without confirmation dialog
+    * [OPENMEETINGS-1342] - Incorrect user type set when user enter to the OpenMeeitings via plugins
+    * [OPENMEETINGS-1344] - MD5 should not be used for password encryption
+    * [OPENMEETINGS-1349] - Custom address states sets to NULL while restoring from backup
+    * [OPENMEETINGS-1350] - rtmpT connection problem
+    * [OPENMEETINGS-1359] - Links to apache-extras.org should be removed from the site
+    * [OPENMEETINGS-1361] - Room name is shown incorrectly when guest ente to the rom
+    * [OPENMEETINGS-1365] - Network Test Page error and fix URL path
+    * [OPENMEETINGS-1370] - JRE 8 is blocking screen sharing/recording by default
+    * [OPENMEETINGS-1371] - After scaling a document scrolling does not work on the whiteboard
+    * [OPENMEETINGS-1372] - openmeetings-flash is not compilable under OS windows
+    * [OPENMEETINGS-1377] - Backup fails when appointment has deleted room
+    * [OPENMEETINGS-1379] - XSS in Chat window leading to DOS
+    * [OPENMEETINGS-1380] - Chat messages are not being imported
+    * [OPENMEETINGS-1384] - SIP dial to room need to be fixed
+    * [OPENMEETINGS-1385] - Moving Uploaded Images
+    * [OPENMEETINGS-1396] - Swf selection should be improved
+    * [OPENMEETINGS-1399] - OpenMeetings is vulnerable to session fixation
+    * [OPENMEETINGS-1400] - Admin>Conference Rooms>Appointment Room Checkbox
+    * [OPENMEETINGS-1402] - Screen Sharing issue with Greek language
+    * [OPENMEETINGS-1406] - View profile form is broken
+    * [OPENMEETINGS-1410] - Om failed to install using Oracle
+    * [OPENMEETINGS-1411] - allowSameURLMultipleTimes parameter for secure hash is broken
+    * [OPENMEETINGS-1412] - Window too big when changing resolution in Audio-Video Recording Test Application
+    * [OPENMEETINGS-1414] - spring-mvc and batik need to be removed
+    * [OPENMEETINGS-1416] - Users with moderator's flag in usergroup do not become moderators in rooms.
+    * [OPENMEETINGS-1417] - Check/uncheck of moderator flag in usergroups doesn't work.
+    * [OPENMEETINGS-1422] - WB is not usable for the appointment room
+    * [OPENMEETINGS-1423] - Aspect ration is being changed for WB video
+    * [OPENMEETINGS-1432] - Recording download from Moodle is broken
+    * [OPENMEETINGS-1433] - WB vertical tools panel is broken
+    * [OPENMEETINGS-1434] - Only the first group is added in ATTRIBUTE mode
+    * [OPENMEETINGS-1435] - Whiteboard Pointer in OM-3.1.2 gives wrong user name
+    * [OPENMEETINGS-1438] - Recordings permission check is broken
+    * [OPENMEETINGS-1442] - Remote keyboard is not working in screen-sharing app
+    * [OPENMEETINGS-1443] - Invitations are broken
+    * [OPENMEETINGS-1444] - Language editor is broken
+
+** Improvement
+    * [OPENMEETINGS-16] - Missing functionality in SOAP/REST API
+    * [OPENMEETINGS-413] - A good idea could be to add default parameter like default country, default language, default domain, etc
+    * [OPENMEETINGS-649] - Add email management functions to Om Admin
+    * [OPENMEETINGS-1356] - Build should be speed up by reducing forking
+    * [OPENMEETINGS-1357] - maven-dependency-plugin should be used to download/unpack OpenLaszlo
+    * [OPENMEETINGS-1360] - Library versions should be updated (3.1.2)
+    * [OPENMEETINGS-1382] - Update default avatar of user
+    * [OPENMEETINGS-1383] - Updated French translation for OpenMeetings 3.1.1/3.1.1+
+    * [OPENMEETINGS-1393] - Missing text strings are not internationalized for translation
+    * [OPENMEETINGS-1403] - External cameras should be supported
+    * [OPENMEETINGS-1405] - Appointment dialog should be simplified
+    * [OPENMEETINGS-1419] - Connect to Oracle DB with Service Name through Web Installer
+
+** Task
+    * [OPENMEETINGS-90] - Default Country
+
+** Wish
+    * [OPENMEETINGS-853] - temporary uploaded files
+
+
+Release Notes - Openmeetings - Version 3.1.1
+================================================================================================================
+** Vulnerability
+    * CVE-2016-0783 - Predictable password reset token
+    * CVE-2016-0784 - ZIP file path traversal
+    * CVE-2016-2164 - Arbitrary file read via SOAP API
+    * CVE-2016-2163 - Stored Cross Site Scripting in Event description
+
+** Bug
+    * [OPENMEETINGS-1328] - ConfirmAjaxCallListener should be changed on standard wicket dialog in the MessagesContactsPanel
+    * [OPENMEETINGS-1339] - Poll results shows uncorrectly
+    * [OPENMEETINGS-1341] - White page is shown when user try to reset password
+    * [OPENMEETINGS-1343] - Release signatures should be created automatically
+    * [OPENMEETINGS-1346] - Error while import a backup from OM version 3.0.2
+    * [OPENMEETINGS-1347] - missing sort functionality in administration view
+    * [OPENMEETINGS-1348] - Backup import with LDAP users from 2.1.0 fails
+    * [OPENMEETINGS-1351] - Call for Logo page does not say where to send contributions
+    * [OPENMEETINGS-1354] - Backup zip is being extracted without necessary checks
+    * [OPENMEETINGS-1355] - random UUID should be user to generate password reset hash
+
+** Improvement
+    * [OPENMEETINGS-1337] - Library versions should be updated (3.1.1)
+
+
+Release Notes - Openmeetings - Version 3.1.0
+================================================================================================================
+** Sub-task
+    * [OPENMEETINGS-1118] - SOAP/REST methods need to be implemented using CXF
+    * [OPENMEETINGS-1277] - roomtype in laszlo code need to be changed
+    * [OPENMEETINGS-1278] - newmessage and some other dialogs need to be replaced with HTML5 dialogs
+    * [OPENMEETINGS-1285] - Number of servlets need to be reduced
+    * [OPENMEETINGS-1286] - Srceensharing is not started
+
+** Bug
+    * [OPENMEETINGS-570] - Some issues with device settings and attach Camera
+    * [OPENMEETINGS-823] - Images are not dragged on whiteboard correctly if user re-enter to the room
+    * [OPENMEETINGS-887] - Global chat is not implemented completly for OM 3.0
+    * [OPENMEETINGS-992] - upload image in profile
+    * [OPENMEETINGS-1237] - Desktop-sharing: keyboard input gets duplicated or triplicated.
+    * [OPENMEETINGS-1252] - Allow/deny screen sharing and remote control does not work as expected
+    * [OPENMEETINGS-1255] - Incorrect work of "Show contact data to contacts only"
+    * [OPENMEETINGS-1258] - The latest chat messeages are not shown in the global chat
+    * [OPENMEETINGS-1260] - Period invitation created from room is shifted one month
+    * [OPENMEETINGS-1261] - docs folder should removed from 3.0.x sources
+    * [OPENMEETINGS-1263] - component.getString() should not be called from constructor
+    * [OPENMEETINGS-1264] - "Old style" confirm dialogs should be replaced with jquery-ui confirmations
+    * [OPENMEETINGS-1266] - Width/height parameters are missing in RecordingDTO
+    * [OPENMEETINGS-1268] - Error while use wsdl service
+    * [OPENMEETINGS-1269] - 'Internal Error' Message on Deleting / Selecting a User in Admin/User Panel
+    * [OPENMEETINGS-1271] - Maximum number of users in restricted room need to be enlarged
+    * [OPENMEETINGS-1272] - Exception and Internal Errror When "To complete your registration please click on the following link"
+    * [OPENMEETINGS-1273] - Poll error
+    * [OPENMEETINGS-1274] - After registration I don't see confirmation
+    * [OPENMEETINGS-1275] - Invalid invitation generates for contact if creat few invitations
+    * [OPENMEETINGS-1276] - Trunk should be merged with 3.1.x
+    * [OPENMEETINGS-1281] - Bad URL to download language files to translate in OpenMeetings website
+    * [OPENMEETINGS-1283] - It is impossible to remove moderator permissions given to a user
+    * [OPENMEETINGS-1284] - Incorrect display of a video player
+    * [OPENMEETINGS-1287] - Mail templates are excluded from the build artefact
+    * [OPENMEETINGS-1288] - Search User page is broken
+    * [OPENMEETINGS-1292] - OM 3.1 When clic on Upload file picture button profile, nothings happens
+    * [OPENMEETINGS-1293] - OM 3.1 When clic on Conference Room button, show turning circle and nothing happens
+    * [OPENMEETINGS-1295] - OM 3.0.7 - No upload image for widget user 
+    * [OPENMEETINGS-1296] - Unable to upload image to profile
+    * [OPENMEETINGS-1297] - svn tree need to be restructured
+    * [OPENMEETINGS-1299] - In Application_zh_CN.properties file, from entry 1465 to entry 1600, we should have Chinese entries, but there are still English entries.
+    * [OPENMEETINGS-1303] - Report a bug URL
+    * [OPENMEETINGS-1308] - "File tree" is broken in room after installation
+    * [OPENMEETINGS-1309] -  Issue with playing the recordings in OM 3.1.0
+    * [OPENMEETINGS-1310] - Flash permission dialog is not displayed
+    * [OPENMEETINGS-1312] - "User recording" message is not removed on recording stop
+    * [OPENMEETINGS-1314] - A no user receive an invitation  and he tries to send an invitation 
+    * [OPENMEETINGS-1316] - Older timezone's in OM
+    * [OPENMEETINGS-1317] - Whiteboard is not displayed for guests in the restricted moderated rooms
+    * [OPENMEETINGS-1318] - Firstname and lastname are shown in the userlist when last user exit from the restricted room
+    * [OPENMEETINGS-1320] - Whiteboard is not saved
+    * [OPENMEETINGS-1321] - Files are not shown correctly when contact enter to the restricted room as moderator
+    * [OPENMEETINGS-1322] - Chat is not shown in the room when document loads on whiteborad
+    * [OPENMEETINGS-1323] - Error is thrown to the log file during conversion recording
+    * [OPENMEETINGS-1326] - Password is not verified when owner send invitation with password
+    * [OPENMEETINGS-1329] - "null" adds to the Subject when user send private masage to contact
+    * [OPENMEETINGS-1331] - Openmeeting is not responsed when moderator kick user from the room
+    * [OPENMEETINGS-1332] - Vote is not work correctly
+    * [OPENMEETINGS-1333] - Recording and sharing is not started when contact try to start recording or sharing 
+    * [OPENMEETINGS-1334] - It's impossible to invite om user to the my rooms
+    * [OPENMEETINGS-1335] - Screen sharing icons and favicon need to be updated
+    * [OPENMEETINGS-1336] - User can not enter to group room
+    * [OPENMEETINGS-1338] - Screen sharing application failed to connect to the server
+    * [OPENMEETINGS-1340] - Moderator can't kick user from the conference room
+
+** Improvement
+    * [OPENMEETINGS-794] - Add a possibility to enter brief name for users with same invitation url (grouped mail)
+    * [OPENMEETINGS-846] - Invitation of a complete usergroup as a one-click operation
+    * [OPENMEETINGS-1245] - Offer drop-down list for inviting users when in conference room
+    * [OPENMEETINGS-1256] - Fetch users from AD into contacts
+    * [OPENMEETINGS-1259] - Library versions should be updated (3.1.0)
+    * [OPENMEETINGS-1262] - Install wizard need to be updated to use wicket-jquery-ui
+    * [OPENMEETINGS-1270] - Outdated documentation
+    * [OPENMEETINGS-1279] - swf8 code need to be converted to swf11
+    * [OPENMEETINGS-1290] - Room SIP# should be displayed as a hint
+    * [OPENMEETINGS-1294] - OM 3.1.0 spanish translation attached
+    * [OPENMEETINGS-1304] - CLONE - In the general interface, provide a way to access links to recordings, which can be shared with others (both registered users and external people).
+    * [OPENMEETINGS-1306] - modifica dei campi e grafica
+    * [OPENMEETINGS-1313] - Support for Google Analytics scripts should be added
+
+** Task
+    * [OPENMEETINGS-1302] - Current maven build doesn't create source artifact
+    * [OPENMEETINGS-1305] - REST/SOAP should be tested
+    * [OPENMEETINGS-1311] - Outdated jquery.ui.menubar should be replaced with jqueryui menu component
+
+** Test
+    * [OPENMEETINGS-1315] - build code sucess, but run red5.bat happen error
+
+
+Release Notes - Openmeetings - Version 3.0.7
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-1211] - the use of icons in users tab is illogical
+    * [OPENMEETINGS-1213] - Error is shown when contact try to send invitation
+    * [OPENMEETINGS-1218] - Wrong birthday date is displayed on the User datails at Administration->Users page
+    * [OPENMEETINGS-1221] - Language is not loaded after changes
+    * [OPENMEETINGS-1230] - Clustering seems not to work as expected
+    * [OPENMEETINGS-1231] - chat bar on landing page without lable an delete function missing
+    * [OPENMEETINGS-1234] - Unable to take backup using GUI or Admin.sh
+    * [OPENMEETINGS-1238] - Share/record screen: go to HTTP STATUS 404- Apache Tomcat page
+    * [OPENMEETINGS-1239] - Can't import REST URL properly
+    * [OPENMEETINGS-1248] - Clustering not working from external system (for ex. Moodle)
+    * [OPENMEETINGS-1249] - Guest can't enter to the room when room is booked via private message
+    * [OPENMEETINGS-1250] - Video is not availble in the interview rooms
+    * [OPENMEETINGS-1251] - When room is full kicked user not redirected to Rooms list
+    * [OPENMEETINGS-1253] - Crash when searching at language editor.
+    * [OPENMEETINGS-1254] - Crash when adding OAuth2 config
+
+** Improvement
+    * [OPENMEETINGS-954] - Need implement OM client for Android devices.
+    * [OPENMEETINGS-1100] - Seperate video/audio permissions capability 
+    * [OPENMEETINGS-1101] - Live presenter activity (typing , drawing)
+    * [OPENMEETINGS-1212] - Library versions should be updated (3.0.7)
+
+** Wish
+    * [OPENMEETINGS-1214] - LDAP import AD groups
+
+
+Release Notes - Openmeetings - Version 3.0.6
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-1202] - Send Invitation error with moodle
+    * [OPENMEETINGS-1203] - Screen sharing is not started when external guest try to start sharing
+    * [OPENMEETINGS-1205] - Invitation is not sent from the toom
+    * [OPENMEETINGS-1207] - Create a poll
+    * [OPENMEETINGS-1208] - default_group_id ...?
+
+** Improvement
+    * [OPENMEETINGS-1197] - Library versions should be updated (3.0.6)
+    * [OPENMEETINGS-1206] - Room service should be updated to be able to generate invitation hash with first and last name
+
+
+Release Notes - Openmeetings - Version 3.0.5
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-889] - "Upload new image" button should have the same style with other buttons
+    * [OPENMEETINGS-1161] - Dashboard start widget is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1168] - Request for contact multi-language + RTL issues
+    * [OPENMEETINGS-1181] - Date pickers are not localized
+    * [OPENMEETINGS-1182] - User entered the room from Joomla plugin is displayed with "null" as lastname
+    * [OPENMEETINGS-1183] - It is impossible to change 'chatOpened' room parameter using modifyRoomParameter SOAP call
+    * [OPENMEETINGS-1185] - Appointments returned by SOAP service get wrong start/end time
+    * [OPENMEETINGS-1187] - Send One-Time Invitation does not work if we Generate URL first.
+    * [OPENMEETINGS-1188] - less data for getRoomById
+    * [OPENMEETINGS-1189] - Room' s session seems to expire in less than 1.5 hours when in rooms
+    * [OPENMEETINGS-1190] - keystore file pw is disclosed in the screen sharing log
+    * [OPENMEETINGS-1196] - Meaningless internal error in case OAuth email is in use
+    * [OPENMEETINGS-1199] - Cluster status is missed on admin->connection page
+    * [OPENMEETINGS-1200] - Main menu items shows incorrectly
+    * [OPENMEETINGS-1201] - Header of moderators list box shows incorrectly
+
+** Improvement
+    * [OPENMEETINGS-1133] - Direct sign-in from another site
+    * [OPENMEETINGS-1184] - Library versions should be updated (3.0.5)
+    * [OPENMEETINGS-1198] - Simplify Database Install
+
+
+Release Notes - Openmeetings - Version 3.0.4
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-878] - Sign Web-Start application with trusted root cert
+    * [OPENMEETINGS-1041] - It is impossible drag and drop recordings to public folder when recordings list is scrolled
+    * [OPENMEETINGS-1055] - Error is thrown and connection is closed when external user try to generate URL and send email invitation
+    * [OPENMEETINGS-1062] - Contact data of other users are shown not all.
+    * [OPENMEETINGS-1063] - When "Show contact data to contacts only" was selected, contact data are not showing for users from contacts.
+    * [OPENMEETINGS-1074] - Sharing of the screen gives remote access to the other user
+    * [OPENMEETINGS-1075] - system does not save the mark "do not ask me" when choosing a camera and video expansion
+    * [OPENMEETINGS-1079] - Synchronous backup does not work through the web interface with a large volume of data
+    * [OPENMEETINGS-1080] - Connection with the server is canceled after recordings
+    * [OPENMEETINGS-1083] - Impossible to add user to group, moderator to room
+    * [OPENMEETINGS-1084] - cannot remove auto created user by invite for conference room 
+    * [OPENMEETINGS-1087] - X-UA-Compatible should be set as first META tag
+    * [OPENMEETINGS-1088] - error installing with mssql
+    * [OPENMEETINGS-1089] - Spanish installation screens contains bad UTF-8 chars
+    * [OPENMEETINGS-1091] - the attendees can chaange the start and end dates of calendar appointment rooms !!!
+    * [OPENMEETINGS-1092] - users can use the calendar room to make conference after the end-date of the conference room!!!
+    * [OPENMEETINGS-1094] - Ldap authorisation is not working correctly if var ldap_search_scope=SUBTREE
+    * [OPENMEETINGS-1098] - Login via OAuth2 is broken due to redirectUri is wrong
+    * [OPENMEETINGS-1102] - Room web service is broken
+    * [OPENMEETINGS-1103] - Pressing 'play' on the video player while a video is already playing starts a new player
+    * [OPENMEETINGS-1105] - Dereferencing Aliases using LDAP and eDirectory.
+    * [OPENMEETINGS-1109] - Appointment with existing room is displayed as appointment with 'appointment special room'
+    * [OPENMEETINGS-1110] - Audio/video is being broadcasted to the room after room exit
+    * [OPENMEETINGS-1114] - LDAP config is not Unicode aware
+    * [OPENMEETINGS-1117] - RTL is not fully supported by OM
+    * [OPENMEETINGS-1121] - Blank field (invited user)
+    * [OPENMEETINGS-1123] - RedirectLoop while trying to install
+    * [OPENMEETINGS-1124] - Calendar interface bug
+    * [OPENMEETINGS-1126] - Timezone bug
+    * [OPENMEETINGS-1127] - Unexpected behaivor when user enter to the room if room type is udefined
+    * [OPENMEETINGS-1128] - users can not be deleted ("ghost users")
+    * [OPENMEETINGS-1131] - New events are not shown in the calendar
+    * [OPENMEETINGS-1134] - Removed folder shows in the "Move to folder..." dropdown box
+    * [OPENMEETINGS-1137] - Reducing load times of rooms via invitations api
+    * [OPENMEETINGS-1139] - When users are in different timezones, the meeting setup was not shown correctly on invitee's caleander
+    * [OPENMEETINGS-1143] - Recordings list order
+    * [OPENMEETINGS-1146] - RTMPS uses rtmpport
+    * [OPENMEETINGS-1149] - "AVI", "FLV" and "Re-convert" buttons are not visible on recordings panel when recordings list box is scrolled
+    * [OPENMEETINGS-1150] - NullPointerException is thrown when user try enter to the room via calendar
+    * [OPENMEETINGS-1151] - Recording Java Application is blocked by Security Settings
+    * [OPENMEETINGS-1153] - "Record started" remains in upper right corner after record was stoped (interviewroom)
+    * [OPENMEETINGS-1154] - Too big waiting time after pressing the "Stop recording" button
+    * [OPENMEETINGS-1156] - The "Allow recording" flag is not checked when screen sharing is started
+    * [OPENMEETINGS-1157] - Calendar web service is broken
+    * [OPENMEETINGS-1159] - Chat is not correctly aligned then language is RTL
+    * [OPENMEETINGS-1160] - Edit user settings is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1162] - Admin->users is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1163] - Admin->OAuth is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1164] - Admin->Servers is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1165] - Admin->Configurations is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1166] - Admin->Groups is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1167] - Admin->Labels is not correctly aligned when language is RTL
+    * [OPENMEETINGS-1169] - Send Message dialog is not properly aligned when RTL language is selected
+    * [OPENMEETINGS-1170] - Profile page is not updated when user changes settings
+    * [OPENMEETINGS-1173] - The "Internal error" is thrown when uncheck the "Create/Modify appointment special room" flag
+    * [OPENMEETINGS-1174] - Unenrolled user not redirected to Rooms list
+    * [OPENMEETINGS-1175] - It is impossible to send private message from the room
+    * [OPENMEETINGS-1177] - Calendar is not properly aligned when RTL language is selected
+
+** Improvement
+    * [OPENMEETINGS-547] - Deferred recordings converting possibility.
+    * [OPENMEETINGS-623] - OpenMeetings\u600e\u4e48\u4fee\u6539\u53d1\u9001\u90ae\u4ef6\u7684\u683c\u5f0f
+    * [OPENMEETINGS-1082] - Library versions should be updated
+    * [OPENMEETINGS-1099] - Build should be ready for web-start code-signing
+    * [OPENMEETINGS-1130] - Emails should be created using templates, not string concatenation
+    * [OPENMEETINGS-1135] - logback config should be updated to use log rotation and keep old logs
+    * [OPENMEETINGS-1136] - Improving portuguese-brazil installation translation
+
+** New Feature
+    * [OPENMEETINGS-1104] - Enable change first day in the Calendar
+
+** Wish
+    * [OPENMEETINGS-1065] - add ability to minimize screen-sharing video
+
+
+Release Notes - Openmeetings - Version 3.0.3
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-270] - MemoryLeak / Dead-Lock in FlvRecorderConverter
+    * [OPENMEETINGS-292] - Inviting people during conference
+    * [OPENMEETINGS-409] - Interview Room (2)
+    * [OPENMEETINGS-452] - LDAP issue. Cannot relogin with user that already was logined before and then logged out
+    * [OPENMEETINGS-532] - Generated hash issue
+    * [OPENMEETINGS-616] - Openmeetings for Drupal got a 500 error
+    * [OPENMEETINGS-680] - The "," symbol is used for the multiple e-mail instead of standard ";" symbol
+    * [OPENMEETINGS-683] - Somtimes vido frame is not visible for other users in the room
+    * [OPENMEETINGS-686] - Recording faild when pause is used
+    * [OPENMEETINGS-697] - Authentification Ldap
+    * [OPENMEETINGS-809] - Global chat issues in rooms
+    * [OPENMEETINGS-888] - Room name is not translated correctly in the "My room" widget
+    * [OPENMEETINGS-915] - Regression in 3.0: Incorrect moderator list update in the room screen.
+    * [OPENMEETINGS-918] - Contacts should not be added to usergroup
+    * [OPENMEETINGS-931] - AD LDAP Authentication on empty install organization choice after first logon: empty list
+    * [OPENMEETINGS-953] - can not upload files while using Tomcat with SSL enabled
+    * [OPENMEETINGS-986] - Oauth2.0 Logon Not Working
+    * [OPENMEETINGS-998] - Audio and Video of recordings are not in sync after a few minutes
+    * [OPENMEETINGS-1007] - Users with externalUserId and externaluserType <> null can't login
+    * [OPENMEETINGS-1012] - Reverted timezone is set by default in invitation window
+    * [OPENMEETINGS-1013] - Profile pictures are not displayed to invited user
+    * [OPENMEETINGS-1015] - Browser time zone is not selected correctly in the invitation window until all java timezones are loaded
+    * [OPENMEETINGS-1019] - RemoteControl: problem with sql
+    * [OPENMEETINGS-1020] - create new user after adding user does not add to DB
+    * [OPENMEETINGS-1022] - cliAdmin is broken (NPE + exclude-files)
+    * [OPENMEETINGS-1023] - ChatMessages are not imported
+    * [OPENMEETINGS-1024] - Add user admin dropdown is broken when postgres is used
+    * [OPENMEETINGS-1026] - Moderator rights are not availble for admin user if enter to the room after simple user
+    * [OPENMEETINGS-1027] - Search button does not work for users
+    * [OPENMEETINGS-1029] - modifyRoomParameter SOAP/REST method is broken
+    * [OPENMEETINGS-1031] - The "New folder" dialogs moves to the bottom of the screen and becomes invisible
+    * [OPENMEETINGS-1032] - search variable in Language Editor produce java.lang.StackOverflowError
+    * [OPENMEETINGS-1034] - openmeetings start always fails with postgresql db on debian
+    * [OPENMEETINGS-1035] - "ant -Ddb=postgres" always fails
+    * [OPENMEETINGS-1037] - LDAP passwords are being printed to the log
+    * [OPENMEETINGS-1038] - PrivateRoom Widget is displayed when dashboard.show.myrooms key is disabled
+    * [OPENMEETINGS-1039] - Interview recording is broken if stop-on-close
+    * [OPENMEETINGS-1042] - .ppt file not open when i upload 
+    * [OPENMEETINGS-1048] - Appointement owner has no moderation rights
+    * [OPENMEETINGS-1050] - User list is missing room users
+    * [OPENMEETINGS-1052] - Room list not displayed after room exit
+    * [OPENMEETINGS-1059] - Language not loaded from user profile.
+    * [OPENMEETINGS-1060] - Strange view of warnings at User editing screen.
+    * [OPENMEETINGS-1061] - Font size list is not visible and availble in the global chat
+    * [OPENMEETINGS-1067] - "Move to folder.." item is not translated correctly on the "Contacts and messages" tab
+    * [OPENMEETINGS-1068] - Error is thrown and connection is closed when move event into Calendar view
+    * [OPENMEETINGS-1069] - Add/remove a user to the default moderator list not working properly
+    * [OPENMEETINGS-1070] - Strange view after auto logout from demo room
+    * [OPENMEETINGS-1076] - Export of localization to file not working.
+    * [OPENMEETINGS-1077] - Max participants in the room work incorrectly
+
+** Improvement
+    * [OPENMEETINGS-96] - Possibility to deny remote control for all when sharing screen
+    * [OPENMEETINGS-360] - Email invited meeting participants to display name not email address
+    * [OPENMEETINGS-942] - Searching for contacts
+    * [OPENMEETINGS-971] - Restrict attendees suggestions
+    * [OPENMEETINGS-984] - Recording auto-repairing should be added
+    * [OPENMEETINGS-1017] - ACLs should be added to the User
+    * [OPENMEETINGS-1021] - Red5 should be updated to the latest stable version
+    * [OPENMEETINGS-1028] - Red5 should be updated to the latest stable version
+    * [OPENMEETINGS-1033] - Improve ldap auth type adding SearchScope variable in config file
+    * [OPENMEETINGS-1036] - Improve User Form for include LDAP domain
+    * [OPENMEETINGS-1040] - Select2 should be used to display/set user groups
+    * [OPENMEETINGS-1049] - no default value for the "Quality of the screen sharing"/default FPS
+
+** New Feature
+    * [OPENMEETINGS-442] - om LDAP users controlled with a group
+    * [OPENMEETINGS-1011] - long time to load openmeetings activity in moodle
+
+** Task
+    * [OPENMEETINGS-964] - LDAP login should be refactored
+
+** Test
+    * [OPENMEETINGS-1025] - Problem with convert recording by ffmpeg
+
+** Wish
+    * [OPENMEETINGS-861] - SOAP user for creating & using om rooms via moodle can log into GUI of OM
+    * [OPENMEETINGS-1066] - re-order fields on screen-sharing applet
+
+
+Release Notes - Openmeetings - Version 3.0.2
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-604] - Pop up message remain same after quitting the room created by Book conference room option in the email
+    * [OPENMEETINGS-916] - Selected recording is not highlighted and should not be moved to other folder
+    * [OPENMEETINGS-976] - Cannot restore an erased key in administration\configuration\key
+    * [OPENMEETINGS-978] - It is impossible to start OM in offline mode
+    * [OPENMEETINGS-983] - Verification URL is not generated correctly for self register users
+    * [OPENMEETINGS-985] - Send Invitation functionality is broken
+    * [OPENMEETINGS-990] - error while playing recording
+    * [OPENMEETINGS-993] - Deleted rooms are now excluded from backup
+    * [OPENMEETINGS-994] - AllowRecording option lock normal user interaction in conference Room.
+    * [OPENMEETINGS-996] - send invitation - generate URL
+    * [OPENMEETINGS-997] - error installing with mssql 
+    * [OPENMEETINGS-1002] - OM theming should be consistent
+    * [OPENMEETINGS-1004] - Internal error is thrown when you search a user on the Search Users Tab
+
+** Improvement
+    * [OPENMEETINGS-982] - ApplicationContext recreation should be avoided
+
+
+Release Notes - Openmeetings - Version 3.0.1
+================================================================================================================
+** Sub-task
+    * [OPENMEETINGS-937] - Screen sharing application should create recordings with size multiple by 16
+
+** Bug
+    * [OPENMEETINGS-913] - Booking is not working via private message
+    * [OPENMEETINGS-917] - Contacts should not be added as default moderator
+    * [OPENMEETINGS-920] - where are the controls to playback a recorded video?
+    * [OPENMEETINGS-934] - screenrecording without sound
+    * [OPENMEETINGS-935] - Names are mixed in contact request email
+    * [OPENMEETINGS-936] - First frame of the recording has size differs from all other frames
+    * [OPENMEETINGS-943] - OM3.0: login with LDAP user not working
+    * [OPENMEETINGS-949] - Add Whiteboard: untranslated string - hardcoded
+    * [OPENMEETINGS-951] - Command line installer fails if path contains spaces
+    * [OPENMEETINGS-952] - Build should be compatible with latest ant
+    * [OPENMEETINGS-956] - Recording frame is not scrolled
+    * [OPENMEETINGS-957] - Screensharing is broken
+    * [OPENMEETINGS-958] - Calendar event start and end date are not displayed correctly in the month vew for IST time zone
+    * [OPENMEETINGS-959] - "Choose Device" Dialog doesn't show (all) devices from flash-settings
+    * [OPENMEETINGS-960] - Long time without changing progressbar when enter OM
+    * [OPENMEETINGS-961] - Calendar event can be canceled by guest
+    * [OPENMEETINGS-965] - Dashboard is malfunctioning when the user language is set to french
+    * [OPENMEETINGS-966] - Invitation links are not working
+    * [OPENMEETINGS-967] - dashboard.show.myrooms and dashboard.show.rssfeed options are not working
+    * [OPENMEETINGS-972] - Default user database
+    * [OPENMEETINGS-975] - Reminder is not sent for calendar event
+    * [OPENMEETINGS-977] - Import of Appointments and UserContacts was broken
+
+** Improvement
+    * [OPENMEETINGS-938] - Recording length field should be filled by converters
+    * [OPENMEETINGS-939] - Not ready recordings should have special icon
+
+
+Release Notes - Openmeetings - Version 3.0.0
+================================================================================================================
+** Sub-task
+    * [OPENMEETINGS-746] - Replace OmTimeZone in User Entity with String tz and fix all dependencies
+    * [OPENMEETINGS-747] - Replace OmTimeZone in Invitations Entity with String tz and fix all dependencies
+    * [OPENMEETINGS-748] - Replace OmTimeZone in MeetingMembers Entity with String tz and fix all dependencies
+    * [OPENMEETINGS-749] - Fix Installer with new timezone handling, default to server timezone in UI
+    * [OPENMEETINGS-750] - Fix Backup importer to be able to import old backups (2.x) to new database schema (3.x) (User, Invitations, MeetingMembers have no OmTimeZone anymore)
+    * [OPENMEETINGS-751] - Remove OmTimeZone Entity and import mechanism for timezones.xml and some cleanup
+    * [OPENMEETINGS-752] - Create Branch and Jenkins Job for Timezone refactoring
+    * [OPENMEETINGS-754] - Fix user admin UI to have timezone as string
+    * [OPENMEETINGS-755] - Fix invitation popup in Flash to not use the OmTimeZones for creating the Invitation
+    * [OPENMEETINGS-758] - Remove OpenLaszlo Admin UI and all related API calls (only if they are not needed somewhere else)
+    * [OPENMEETINGS-759] - Remove Flash UI user settings and related API calls 
+    * [OPENMEETINGS-762] - Callers of TimezoneUtil.getTimezoneByInternalJName should be checked to work as expected
+
+** Bug
+    * [OPENMEETINGS-69] - Conference Room - Chat RTL dosn't function 
+    * [OPENMEETINGS-243] - "Updated" field in Administration -> LDAP panel contains "null" for string for empty value.
+    * [OPENMEETINGS-274] - It is impossible to display "test setup recording" once hidden
+    * [OPENMEETINGS-321] - Recording under OSX throws exception in RecordingConverter
+    * [OPENMEETINGS-337] - interview room - audio does not work when "audio only" is selected
+    * [OPENMEETINGS-348] - zoom synchonization
+    * [OPENMEETINGS-377] - Double clicking in the calendar area create two \u201cEvent details\u201d dialog windows not just one window
+    * [OPENMEETINGS-405] - microphoneRateNormal & microphoneRateBest - not change rate
+    * [OPENMEETINGS-410] - whiteboard first color
+    * [OPENMEETINGS-416] - "Hide actions menu" does not work via SOAP in "restricted" room
+    * [OPENMEETINGS-421] - Reminder to conference issue
+    * [OPENMEETINGS-426] - Html Errors/Problems
+    * [OPENMEETINGS-428] - Refactor User administration to Wicket
+    * [OPENMEETINGS-432] - video only room is coming with white board also
+    * [OPENMEETINGS-435] - Help Help Help openmeetings service is not work at the next day
+    * [OPENMEETINGS-437] - Link "...Edit your profile" form de user home page send the control to a user profile view, not to a edit profile view
+    * [OPENMEETINGS-439] - An LDAP user can't change their own profile picture.
+    * [OPENMEETINGS-444] - Create HTML/Wicket admin backup section
+    * [OPENMEETINGS-445] - Backup Export does not work at all
+    * [OPENMEETINGS-451] - Search in user groups Wicket UI does not work
+    * [OPENMEETINGS-473] - Recorded video Display blank at demo.openmeetings.com
+    * [OPENMEETINGS-481] - When I reserve a room by sending an email, users who connected to this link from an email have the same email address as me
+    * [OPENMEETINGS-486] - Sometimes OM stops responding to clicks
+    * [OPENMEETINGS-494] - Recording gives frame rate of 2 fps
+    * [OPENMEETINGS-503] - Openmeetings does not logout on the Recording panel
+    * [OPENMEETINGS-507] - Error message is shown when user save the Profile settings 
+    * [OPENMEETINGS-513] - Participant of poll can vote more than once in the "My conference room"
+    * [OPENMEETINGS-514] - Some extra links are displayed on the "Choose Usergroup" dialog
+    * [OPENMEETINGS-537] - Pop menu  in conference for files shows "Delete folder"
+    * [OPENMEETINGS-544] - some bug with SIP
+    * [OPENMEETINGS-560] - It\u2019s possible to add several records with the same key value in configuration.
+    * [OPENMEETINGS-564] - Types of rooms are not localized
+    * [OPENMEETINGS-566] - No default timezone selection in registration/sign up when user is in timezone +12
+    * [OPENMEETINGS-572] - Empty fields are replaced with string "null" after export&import
+    * [OPENMEETINGS-575] - Name of the restricted and interview rooms is not displayed when user enter to this room
+    * [OPENMEETINGS-579] - In any room not close the video and audio settings windows. Video is not broadcasting.
+    * [OPENMEETINGS-580] - Smslib 3.5.3 should be used.
+    * [OPENMEETINGS-582] - 2.0 RoomPoll and Configs restore failed
+    * [OPENMEETINGS-584] - Main window is scrolled when select value from dropdown box
+    * [OPENMEETINGS-586] - FileItem owner_id is not replaced with new id while system import
+    * [OPENMEETINGS-587] - Exclusive audio by hotkey is broken
+    * [OPENMEETINGS-590] - Useless "SIP Settings" section in the user screen.
+    * [OPENMEETINGS-591] - Whiteboard presentacion from PPT page controll event randomly broken
+    * [OPENMEETINGS-596] - ffmpeg is not work in current version
+    * [OPENMEETINGS-600] - RSS Feed
+    * [OPENMEETINGS-601] - User Profile picture
+    * [OPENMEETINGS-603] - Conference Room Types List doesn't display textual content - Book Conference Room Option Selected while Sending an Email 
+    * [OPENMEETINGS-609] - The end time shown under the Book Conference Room option in New Message is Incorrect
+    * [OPENMEETINGS-617] - Impossible to refresh video using button "(Re) Start audio/video or change device settings"
+    * [OPENMEETINGS-618] - Incorrect translation
+    * [OPENMEETINGS-619] -  Problems with a microphone 
+    * [OPENMEETINGS-620] - Self-Register, Forgot password and login by LDAP should be implemented
+    * [OPENMEETINGS-625] - Profile Pictures not working on LDAP Accounts
+    * [OPENMEETINGS-627] - Private rooms disappear after use
+    * [OPENMEETINGS-628] - Exception is thrown when search user on the Profile->Search users tab
+    * [OPENMEETINGS-629] - Event is not deleted from Calendar
+    * [OPENMEETINGS-630] - Event is not resized in calendar
+    * [OPENMEETINGS-632] - Some links are mistaked in html version of OM
+    * [OPENMEETINGS-633] - Event is not created if title is empty.
+    * [OPENMEETINGS-634] - No menu accessable after file upload, in a special condition
+    * [OPENMEETINGS-635] - Administration / Configuration : default_lang_id documentation
+    * [OPENMEETINGS-640] - Room is not resized in IE
+    * [OPENMEETINGS-642] - The "Import" and "Export" buttons are missed on the Administrator->Language editor tab
+    * [OPENMEETINGS-643] - User details is not updated in the HTML version
+    * [OPENMEETINGS-645] - Can't create installation wizard
+    * [OPENMEETINGS-647] - Drag&Drop Issue Openmeetings 1.8.8 r4555
+    * [OPENMEETINGS-650] - Can't create conference room
+    * [OPENMEETINGS-651] - User can not login
+    * [OPENMEETINGS-654] - Interview room is broken
+    * [OPENMEETINGS-655] - Calendar is not localized
+    * [OPENMEETINGS-657] - can not convert file
+    * [OPENMEETINGS-658] - Event creates in the Calendar with wrong start and end time
+    * [OPENMEETINGS-660] - Types of reminder are not localized
+    * [OPENMEETINGS-661] - Invitation is not implemented in the HTML Calendar
+    * [OPENMEETINGS-663] - OM Installer is not localized
+    * [OPENMEETINGS-664] - OM is not installed in IE 10 browser.
+    * [OPENMEETINGS-665] - File upload in the room is broken
+    * [OPENMEETINGS-666] - Main menu displays incorrectly in the IE browser.
+    * [OPENMEETINGS-667] - Recordings are not viewable on iPad
+    * [OPENMEETINGS-669] - Recording is broken
+    * [OPENMEETINGS-672] - in recordings page ,people cant logout
+    * [OPENMEETINGS-673] - Rooms form is not shown correctly in the HTML version
+    * [OPENMEETINGS-674] - Image is not uploaded on the "Profile" tab in the HTML version of OM
+    * [OPENMEETINGS-676] - User can not login
+    * [OPENMEETINGS-679] - Share/record screen
+    * [OPENMEETINGS-682] - Admin password length is not checked while installing
+    * [OPENMEETINGS-687] - Microphone is unmuted when user refresh video frame
+    * [OPENMEETINGS-688] - Library versions should be bumped
+    * [OPENMEETINGS-689] - Russian installation encoding is broken in Ubuntu.
+    * [OPENMEETINGS-691] - screen sharing / recording couldn't starting
+    * [OPENMEETINGS-693] - Tomcat 7 patch should be removed from OM build
+    * [OPENMEETINGS-695] - Rooms page is not completly in the HTML version
+    * [OPENMEETINGS-696] - Choose device dialog is not availble in the restricted room
+    * [OPENMEETINGS-702] - when uploading file in a room, after click start upload,  return a window with HTTP-ERROR: 500  
+    * [OPENMEETINGS-703] - Invitation is not implemented to the HTML Calendar
+    * [OPENMEETINGS-704] - Calendar UI - Unify button list (Cancel always on right side)
+    * [OPENMEETINGS-705] - Not possible to enter any conference room
+    * [OPENMEETINGS-707] - Calendar UI Creation Popup - clean up UI elements
+    * [OPENMEETINGS-708] - Calender UI Popup shows empty input values when Calendar UI is loaded second time
+    * [OPENMEETINGS-709] - Calendar UI Popup - no need for delete button if you create a new event
+    * [OPENMEETINGS-711] - Calendar UI add external attendee's
+    * [OPENMEETINGS-714] - Calendar does not send any invitations to the attendees
+    * [OPENMEETINGS-715] - Calendar does not send any update email if you change a calendar event to the attendees
+    * [OPENMEETINGS-716] - Calendar does not send any delete email if you delete a calendar event to the attendees
+    * [OPENMEETINGS-718] - Newly created users are unable to login
+    * [OPENMEETINGS-719] - Calendar UI delete button has no confirmation
+    * [OPENMEETINGS-720] - Calendar throws server error if any calendar event is saved (only tested with new events so far)
+    * [OPENMEETINGS-726] - Internal users do not show calendar events of events that you have been added to
+    * [OPENMEETINGS-729] - Empty / null values in email_username/password throws Exception when processing emails
+    * [OPENMEETINGS-730] - Cannot save empty value for configuration key in HTML5 UI (for instance username / pas for email configuration)
+    * [OPENMEETINGS-736] - Calendar UI - Month view does not resize to browser window by default
+    * [OPENMEETINGS-738] - Wrong successful registration message behavior
+    * [OPENMEETINGS-741] - Failed to change password
+    * [OPENMEETINGS-742] - Calendar UI - week and day view pretty useless when you can't select any day
+    * [OPENMEETINGS-743] - HTML Version Forgotten  your password email link does not work 
+    * [OPENMEETINGS-744] - Private message does not send in the HTML version
+    * [OPENMEETINGS-756] - Remove OpenLaszlo/Flash Calendar UI and Server side components API Calls/DTOs
+    * [OPENMEETINGS-757] - Several issues with external and internal meeting members
+    * [OPENMEETINGS-763] - Command line admin: --drop option is broken
+    * [OPENMEETINGS-764] - Plugins should work with OM 3.0.0
+    * [OPENMEETINGS-765] - Wicket should be used for email generation
+    * [OPENMEETINGS-768] - User is not enter to the room when rtmp port is not set correctly
+    * [OPENMEETINGS-769] - Calendar UI - Event details with link to room
+    * [OPENMEETINGS-770] - when i click button  share/recording screen , i get do download [ public 7.jnlp], not working properly
+    * [OPENMEETINGS-771] - Dashboard is not shown correctly when user exit from the room.
+    * [OPENMEETINGS-773] - Deleted users are shown in the Usergroups
+    * [OPENMEETINGS-776] - Contacts should be visible for owner and admin only
+    * [OPENMEETINGS-777] - SOAP/REST API should be fixed to create appointments as HTML5 web client
+    * [OPENMEETINGS-780] - Upload pictures and other documents on the white board, has been in the transition state.
+    * [OPENMEETINGS-784] - SOAP API service "modifyRoomParameter" converts "paramValue" into String
+    * [OPENMEETINGS-785] - Messsage " You have successfully signed up. An email with a verification code will be sent to your mailbox." comes up even if it is not supposed to
+    * [OPENMEETINGS-786] - Loading symbol in Wicket and Flash should look the same
+    * [OPENMEETINGS-787] - top navigation gone
+    * [OPENMEETINGS-788] - As soon as you hit the "start conference" button the video freezes and just nothing happens
+    * [OPENMEETINGS-789] - Interview room recording in 2.1.1
+    * [OPENMEETINGS-796] - Install Wizard displays wrong value for red5SipEnable
+    * [OPENMEETINGS-799] - SOAP methods RoomService.{getRooms,getRoomsWithCurrentUsers} and UserService.getUsersByOrganisation are broken
+    * [OPENMEETINGS-803] - Image files are not visible for attendees on whiteboard
+    * [OPENMEETINGS-804] - updateRoomWithModerationQuestionsAudioTypeAndHideOptions sets isAudioOnly always to true
+    * [OPENMEETINGS-806] - addNewUser SOAP method doe not return valid error code
+    * [OPENMEETINGS-808] - Installation using Derby default database configuration seems to have performance issues
+    * [OPENMEETINGS-810] - Entering interview room doesnt have option to select camera size - it inhetits the last used size
+    * [OPENMEETINGS-815] - Exception in sign up
+    * [OPENMEETINGS-818] - Room login via secureHash is broken
+    * [OPENMEETINGS-819] - Zoom is not synchronyzed on whiteboard
+    * [OPENMEETINGS-821] - Can't upload file
+    * [OPENMEETINGS-822] - Closed room was created by addRoom and addRoomWithModeration REST/SOAP methods
+    * [OPENMEETINGS-830] - Recording is broken without screen sharing
+    * [OPENMEETINGS-832] - SOAP doesn't work
+    * [OPENMEETINGS-835] - no proper db-type option for postgresql db (Command Line Admin)
+    * [OPENMEETINGS-836] - OM layout error  - item from vicket is hide the room chat elements
+    * [OPENMEETINGS-841] - Only the first user in a room is displayed and can be heard by others
+    * [OPENMEETINGS-842] - External users should not be redirected to dashboard
+    * [OPENMEETINGS-844] - Invitations are broken after last refactoring
+    * [OPENMEETINGS-848] - RoomService.getRoomCounters REST/SOAP method is not working
+    * [OPENMEETINGS-849] - some remains after the purge of deleted recordings and a system cleanup via admin.sh
+    * [OPENMEETINGS-851] - There is no way to use uploaded files in an interview room
+    * [OPENMEETINGS-852] - Whiteboard Objects not clickable
+    * [OPENMEETINGS-855] - NPE using ./admin.sh -v -f --cleanup
+    * [OPENMEETINGS-856] - Invitation link is broken
+    * [OPENMEETINGS-859] - Audio and Video in recordings is no more in sync
+    * [OPENMEETINGS-860] - Invite window is opened with long delay
+    * [OPENMEETINGS-864] - Exception is thrown when update event in the calendar
+    * [OPENMEETINGS-865] - Upload buttons has artifacts
+    * [OPENMEETINGS-866] - NPE if frontend register is not allowed
+    * [OPENMEETINGS-868] - User creation via SOAP availability should be controlled by separate option
+    * [OPENMEETINGS-869] - Email subject is not displayed correctly for UTF-8 charset
+    * [OPENMEETINGS-870] - Plugins should work in version 3.0
+    * [OPENMEETINGS-871] - Internal error is thrown when search user on the Search users tab
+    * [OPENMEETINGS-872] - The "to" field is not filed in the "Write new message dialog"
+    * [OPENMEETINGS-873] - Ajax error is thrown when click on the "Show user profile" icon
+    * [OPENMEETINGS-875] - Widgets title are not translated when user change language
+    * [OPENMEETINGS-876] - The "Click here to enter room" link is attached to cancel email notification.
+    * [OPENMEETINGS-877] - New line "<br/>" tag does not applied for invitation message
+    * [OPENMEETINGS-880] - 3.0 regression: "Forgotten your password?" does not work on the login screen.
+    * [OPENMEETINGS-882] - OpenMeetings calendar allows create events with the end date/time earlier than the start date/time
+    * [OPENMEETINGS-883] - Strange behaviour during the external guest entering
+    * [OPENMEETINGS-884] - Regression in 3.0: Drop-down lists in the user registration screen work incorrectly in Google Chrome
+    * [OPENMEETINGS-885] - Record is not played under Chrome browser
+    * [OPENMEETINGS-886] - Impossible to save editable fields in My Profile.
+    * [OPENMEETINGS-890] - The "Login" field is not displayed on the connection panel.
+    * [OPENMEETINGS-891] - Wrong birthday date is displayed on the profile->edit settings panel
+    * [OPENMEETINGS-892] - "Add user" button is disabled when add new group
+    * [OPENMEETINGS-893] - Removed user is not added to usergroup again
+    * [OPENMEETINGS-898] - Time zone is not defined correctly on sign in page
+    * [OPENMEETINGS-899] - Calendar event start and end time are not displayed correctly
+    * [OPENMEETINGS-900] - Deleted contact is selected when user invite external guest to calendar invitation
+    * [OPENMEETINGS-901] - Password is not requested when password protected invitation send to external guest.
+    * [OPENMEETINGS-902] - Records are not created correctly
+    * [OPENMEETINGS-904] - Default landing zone
+    * [OPENMEETINGS-906] - Cannot create new group with users
+    * [OPENMEETINGS-907] - "password is required" message is displayed when "Password protected" checkbox is not  checked
+    * [OPENMEETINGS-908] - Calendar event start and end date are not displayed correctly in the month vew
+    * [OPENMEETINGS-909] - Event owners is not receive email notification
+    * [OPENMEETINGS-910] - Contacts are availble to search on the Search user page
+    * [OPENMEETINGS-912] - Email disappears when move emial to the new folder
+    * [OPENMEETINGS-914] - "Mark unread" action does not work on Contacts and message page
+    * [OPENMEETINGS-919] - Access logs will not be generated
+    * [OPENMEETINGS-922] - Add folder button does not add a folder.
+    * [OPENMEETINGS-923] - Drag and drop of files in the recordings section does not work
+    * [OPENMEETINGS-924] - deleting recordings?
+    * [OPENMEETINGS-925] - Recording details previously showed the room name not the id
+    * [OPENMEETINGS-927] - Memory leak in OM wicket application
+    * [OPENMEETINGS-930] - getInvitationHash method allow creation of invalid users (login too small)
+    * [OPENMEETINGS-932] - SIP dialer menu item is not availble in the OM 3.x
+
+** Improvement
+    * [OPENMEETINGS-167] - Main menu of OM
+    * [OPENMEETINGS-168] - Adding system date on dashboard
+    * [OPENMEETINGS-183] - Replacing "Timezone" column in "Users search" interface with a most important information = "statue" (connected /  absent).
+    * [OPENMEETINGS-273] - calendar time is not updating dynamically
+    * [OPENMEETINGS-280] - Update ATutor Module for OM
+    * [OPENMEETINGS-358] - Remove or hide the "Domian" selection from the "Login" dialog when there is only one "Domain"
+    * [OPENMEETINGS-368] - Allow users to zoom their view of the Whiteboard by default and not being controlled by "Draw on the Whiteboard" permissions
+    * [OPENMEETINGS-375] - Allow an administrative option to control whether to display the "Mute microphone globally" dialog box or not
+    * [OPENMEETINGS-429] - [Wicket] Language admin should be implemented
+    * [OPENMEETINGS-484] - Poor quality of bitmapped pictures in pdf files on the whiteboard.
+    * [OPENMEETINGS-548] - Open meetings in a new window or tab
+    * [OPENMEETINGS-556] - GSOC: Faster screen sharing
+    * [OPENMEETINGS-558] - GSOC: Need wysiwyg editor Wicket component
+    * [OPENMEETINGS-574] - wicket-jquery-ui should be used instead of adding jquery-ui manually to every page
+    * [OPENMEETINGS-578] - Latest Red5 server should be used in OM
+    * [OPENMEETINGS-583] - Ability to disable enhanced microphone should be added
+    * [OPENMEETINGS-589] - Configurable hot key for Mute/Unmute should be added
+    * [OPENMEETINGS-594] - Add translated word in thai language
+    * [OPENMEETINGS-610] - push2talk button
+    * [OPENMEETINGS-612] - Dashboard need to be implemented
+    * [OPENMEETINGS-615] - User Profile panel need to be implemented
+    * [OPENMEETINGS-626] - Recordings panel need to be added
+    * [OPENMEETINGS-631] - Updated French translation
+    * [OPENMEETINGS-637] - Admin: Connections panel need to be implemented
+    * [OPENMEETINGS-638] - Room enter/exit should be implemented
+    * [OPENMEETINGS-639] - Installer should be implemented on Wicket
+    * [OPENMEETINGS-646] - Emotions should be added to the chat
+    * [OPENMEETINGS-685] - Japanese translation update for v2.1.1 / v3.1
+    * [OPENMEETINGS-692] - HTML admin should be improved to highlight record which changes 
+    * [OPENMEETINGS-701] - Wicket HTML templates should be stored unarchived
+    * [OPENMEETINGS-727] - no warning for too short login names
+    * [OPENMEETINGS-772] - Project tree structure should be updated
+    * [OPENMEETINGS-778] - Cannot install simplified Chinese
+    * [OPENMEETINGS-798] - MSSQL support should be added to OM
+    * [OPENMEETINGS-820] - No function to match user groups with rooms via SOAP
+    * [OPENMEETINGS-854] - SOAP/REST call getFlvRecordingByExternalUserId should take into account both external id and type
+
+** New Feature
+    * [OPENMEETINGS-152] - Background image
+    * [OPENMEETINGS-491] - LDAP authentication filter
+    * [OPENMEETINGS-576] - Suggestion about the tunnelling implementation.
+    * [OPENMEETINGS-656] - Callback URL when client drop/log out from room
+    * [OPENMEETINGS-802] - Integration with Chamilo LMS
+    * [OPENMEETINGS-857] - sound/voice warning when disconnected
+
+** Task
+    * [OPENMEETINGS-81] - Unify Upload Components
+    * [OPENMEETINGS-721] - is it possible to add new user from soap method?
+    * [OPENMEETINGS-740] - Login via OAuth2
+    * [OPENMEETINGS-760] - Removing all OpenLaszlo /Flash UI that is no more maintained all all connected server side API calls.
+    * [OPENMEETINGS-767] - Redundant fields should be removed from MeetingMember object
+
+** Wish
+    * [OPENMEETINGS-38] - Default language
+    * [OPENMEETINGS-534] - How to set When the user is registered, need administrator audit to register?
+    * [OPENMEETINGS-607] - Refine the UI
+    * [OPENMEETINGS-622] - Removing the menu items and customizing dashboard
+
+
+Release Notes - Openmeetings - Version 2.2.0 Apache Release
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-671] - Calendar is shown incompletely when book conference room
+    * [OPENMEETINGS-763] - Command line admin: --drop option is broken
+    * [OPENMEETINGS-789] - Interview room recording in 2.1.1
+    * [OPENMEETINGS-791] - Backup import is broken
+    * [OPENMEETINGS-799] - SOAP methods RoomService.{getRooms,getRoomsWithCurrentUsers} and UserService.getUsersByOrganisation are broken
+    * [OPENMEETINGS-803] - Image files are not visible for attendees on whiteboard
+    * [OPENMEETINGS-804] - updateRoomWithModerationQuestionsAudioTypeAndHideOptions sets isAudioOnly always to true
+    * [OPENMEETINGS-806] - addNewUser SOAP method doe not return valid error code
+    * [OPENMEETINGS-810] - Entering interview room doesnt have option to select camera size - it inhetits the last used size
+    * [OPENMEETINGS-811] - Recordings does not downloaded via Google Chrome browser
+    * [OPENMEETINGS-819] - Zoom is not synchronyzed on whiteboard
+    * [OPENMEETINGS-832] - SOAP doesn't work
+    * [OPENMEETINGS-835] - no proper db-type option for postgresql db (Command Line Admin)
+    * [OPENMEETINGS-837] - "Choose Device" Dialog stops working after a few Changes
+    * [OPENMEETINGS-842] - External users should not be redirected to dashboard
+    * [OPENMEETINGS-848] - RoomService.getRoomCounters REST/SOAP method is not working
+
+** Improvement
+    * [OPENMEETINGS-368] - Allow users to zoom their view of the Whiteboard by default and not being controlled by "Draw on the Whiteboard" permissions
+    * [OPENMEETINGS-556] - GSOC: Faster screen sharing
+    * [OPENMEETINGS-798] - MSSQL support should be added to OM
+    * [OPENMEETINGS-820] - No function to match user groups with rooms via SOAP
+
+** New Feature
+    * [OPENMEETINGS-491] - LDAP authentication filter
+
+** Task
+    * [OPENMEETINGS-790] - Red5 version in 2.x branch should be bumped
+
+
+Release Notes - Openmeetings - Version 2.1.1 Apache Release
+================================================================================================================
+** Bug
+    * [OPENMEETINGS-432] - video only room is coming with white board also
+    * [OPENMEETINGS-439] - An LDAP user can't change their own profile picture.
+    * [OPENMEETINGS-481] - When I reserve a room by sending an email, users who connected to this link from an email have the same email address as me
+    * [OPENMEETINGS-503] - Openmeetings does not logout on the Recording panel
+    * [OPENMEETINGS-507] - Error message is shown when user save the Profile settings 
+    * [OPENMEETINGS-537] - Pop menu  in conference for files shows "Delete folder"
+    * [OPENMEETINGS-586] - FileItem owner_id is not replaced with new id while system import
+    * [OPENMEETINGS-587] - Exclusive audio by hotkey is broken
+    * [OPENMEETINGS-598] - dont build trunk on JDK 1.7 x64
+    * [OPENMEETINGS-608] - Office file are uploaded but not displayed
+    * [OPENMEETINGS-609] - The end time shown under the Book Conference Room option in New Message is Incorrect
+    * [OPENMEETINGS-618] - Incorrect translation
+    * [OPENMEETINGS-625] - Profile Pictures not working on LDAP Accounts
+    * [OPENMEETINGS-634] - No menu accessable after file upload, in a special condition
+    * [OPENMEETINGS-635] - Administration / Configuration : default_lang_id documentation
+    * [OPENMEETINGS-654] - Interview room is broken
+    * [OPENMEETINGS-670] - The webinar is already closed, you wil be rediredcted to some interesting offerings in X sek
+    * [OPENMEETINGS-687] - Microphone is unmuted when user refresh video frame
+
+** Improvement
+    * [OPENMEETINGS-589] - Configurable hot key for Mute/Unmute should be added
+
+
+Release Notes - Openmeetings - Version 2.1 Apache Release
+================================================================================================================
+** Sub-task
+    * [OPENMEETINGS-448] - Test and fix latest trunk to be able to import all old download zip's
+
+** Bug
+    * [OPENMEETINGS-34] - missing entries in XML language files
+    * [OPENMEETINGS-49] - Synchronisation between Calendar and Dashboard
+    * [OPENMEETINGS-92] - The documents are not deleted from the server after removing them from the system
+    * [OPENMEETINGS-94] - References to the code.google.com need to be updated
+    * [OPENMEETINGS-157] - Registration bug
+    * [OPENMEETINGS-166] - Meeting is created with incorrect start time in the calendar.
+    * [OPENMEETINGS-180] - bug sending invitation
+    * [OPENMEETINGS-196] - Calendar Ical / Simple Mail - double invitation mail
+    * [OPENMEETINGS-212] - Activities and actions: "Deny and remove message " button is not worked
+    * [OPENMEETINGS-243] - "Updated" field in Administration -> LDAP panel contains "null" for string for empty value.
+    * [OPENMEETINGS-251] - Minors layout problems when translating
+    * [OPENMEETINGS-267] - missing translation
+    * [OPENMEETINGS-291] - light does not indicate when the user is speaking
+    * [OPENMEETINGS-310] - Moodle plugin version
+    * [OPENMEETINGS-311] - Language problem after Openmeetings update (accessing from Moodle only)
+    * [OPENMEETINGS-312] - File was null or did not exist: TEST_SETUP_1338945244240.flv
+    * [OPENMEETINGS-314] - Webcam Title of user is username of default OM user
+    * [OPENMEETINGS-316] - ICS attachments for emails not working with Exchange 2003/2007 and Outlook 2003/2007
+    * [OPENMEETINGS-320] - Exception and layout for screensharing/recording client
+    * [OPENMEETINGS-322] - Several Exception in Log
+    * [OPENMEETINGS-327] - Add Restart Save Mail-Queue
+    * [OPENMEETINGS-328] - screen sharing is not closing automatically
+    * [OPENMEETINGS-331] - tooltip for cmd_applyforWhiteBoard room action is not set
+    * [OPENMEETINGS-343] - OM crashes if Invite\u0432 guest with screen sharing rights tries to start screen sharing
+    * [OPENMEETINGS-346] - Screen Sharing does not end with end of meeting
+    * [OPENMEETINGS-362] - Download of profile images broken
+    * [OPENMEETINGS-363] - Some minor bugs in private chat
+    * [OPENMEETINGS-364] - User is not removed from user list when he leaves the room
+    * [OPENMEETINGS-366] - File upload does not show images as options when doing file upload
+    * [OPENMEETINGS-376] - \u201cNotification type\u201d text overflows the drop down data selection area and is partly covered
+    * [OPENMEETINGS-378] - Update Calendar email notification rules to send notification only when data relevant to the users has been changed
+    * [OPENMEETINGS-379] - The Calendar ics format email notification is incorrectly formed
+    * [OPENMEETINGS-380] - Calendar "Add attendee" option has a second option of itself to "Add external" but adding an external attendee does not close this dialog
+    * [OPENMEETINGS-381] - ivy jar in our repository
+    * [OPENMEETINGS-382] - LICENSE file mentions both CDDL and GPL
+    * [OPENMEETINGS-385] - contextmenu  contextmenuitem
+    * [OPENMEETINGS-389] - Create Drupal plugin for OpenMeetings
+    * [OPENMEETINGS-391] - Private and public folder does not appear
+    * [OPENMEETINGS-392] - privateChatTabBottom
+    * [OPENMEETINGS-393] - NumberFormatException while creating user or room
+    * [OPENMEETINGS-394] - save and load whiteboard does not work
+    * [OPENMEETINGS-396] - ICS attachments not recognised in Outlook 2003
+    * [OPENMEETINGS-402] - I cannot open Interview recorded
+    * [OPENMEETINGS-403] - Missing rooms
+    * [OPENMEETINGS-408] - Interview Room (1)
+    * [OPENMEETINGS-415] - NetStream NetStatus event does not work when attached to client object
+    * [OPENMEETINGS-418] - ScreenShare russian charset
+    * [OPENMEETINGS-420] - small problems in the current version
+    * [OPENMEETINGS-422] - Java error: TEST_SETUP_xxx.flv does not exist; javax error : ClientBroadCast Stream; published name=null
+    * [OPENMEETINGS-423] - Installation OM2.0
+    * [OPENMEETINGS-424] - Adjust Stream Volume
+    * [OPENMEETINGS-428] - Refactor User administration to Wicket
+    * [OPENMEETINGS-431] - OpenMeetings behind a proxy doesn't work for screen sharing
+    * [OPENMEETINGS-433] - Add Wicket enabled room administration
+    * [OPENMEETINGS-434] - Create admin area for groups, configurations, ldaps, servers
+    * [OPENMEETINGS-438] - Some bugs
+    * [OPENMEETINGS-440] - Problem in installation process
+    * [OPENMEETINGS-441] - Can't backup
+    * [OPENMEETINGS-445] - Backup Export does not work at all
+    * [OPENMEETINGS-449] - Cannot import backup file
+    * [OPENMEETINGS-450] - Wicket UI locked after accepting download of backup
+    * [OPENMEETINGS-451] - Search in user groups Wicket UI does not work
+    * [OPENMEETINGS-453] - Recordings associated with wrong user after import if already a user was in the database
+    * [OPENMEETINGS-454] - Scrennsharing initiated by invited user ends up in exception report
+    * [OPENMEETINGS-455] - Create RTMPClient to do a load test
+    * [OPENMEETINGS-458] - Missing language string "pluginname"
+    * [OPENMEETINGS-459] - Remove RoomClient from database
+    * [OPENMEETINGS-466] - Screen Sharing window, Chinese Simplified (lang_id=11) text display "?????"
+    * [OPENMEETINGS-467] - No internal user can be selected when planning a meeting
+    * [OPENMEETINGS-469] - Deleted meeting data remains in SIP db tables
+    * [OPENMEETINGS-472] - red5sip rev68 will not run
+    * [OPENMEETINGS-474] - Links to rooms sent via email do not work
+    * [OPENMEETINGS-482] - Network check script hangs after the second "Port" button click 
+    * [OPENMEETINGS-489] - Start recording test hangs if no webcamera connected
+    * [OPENMEETINGS-490] - Wrong directory for test file in "Choose device" window
+    * [OPENMEETINGS-492] - Restoration of backup failed
+    * [OPENMEETINGS-493] - Uploading Libreoffice-format files only results in "Deleted"
+    * [OPENMEETINGS-496] - It's unable to send localized SMS message.
+    * [OPENMEETINGS-498] - Backup fails with Exception
+    * [OPENMEETINGS-502] - Some labels are hardcoded on the System backup tab 
+    * [OPENMEETINGS-504] - Some labels are not translated to russian language
+    * [OPENMEETINGS-505] - Values of the "Unerole User" and "Server Address" fields are mixed on the Administrator -> Connections tab.
+    * [OPENMEETINGS-506] - Localized (russian) file name is not uploaded on the Profile tab
+    * [OPENMEETINGS-509] - Comment is shown incorrectly in the Choose device dialog
+    * [OPENMEETINGS-512] - Files are not uploaded in the rooms
+    * [OPENMEETINGS-515] - Video recording artifacts at the begin of the file
+    * [OPENMEETINGS-516] - After graduation tasks
+    * [OPENMEETINGS-517] - sensSMS flag is not imported/exported by admin.
+    * [OPENMEETINGS-519] - Need to update Configuration page on Openmeetings site.
+    * [OPENMEETINGS-520] - Missing areas on the recorded video
+    * [OPENMEETINGS-521] - The "Show/Copy chat log" and "Delete server chat log" buttons are not available for the Ptivate Chat
+    * [OPENMEETINGS-523] - download manual ghostcript download link is dead
+    * [OPENMEETINGS-524] - Unenroled user is not thrown from the conference room 
+    * [OPENMEETINGS-525] - Font styles icon is enabled for Ptivate Chat if the "Allow font styles" is not enabled for conference room
+    * [OPENMEETINGS-526] - Not enough checking in the screensharing/recording
+    * [OPENMEETINGS-530] - Network testing tool on login page does not work when having OM configured for HTTPS and RTMPS
+    * [OPENMEETINGS-531] - Error Missing[XXXX]
+    * [OPENMEETINGS-536] - In upload dialog "Select file" does not work
+    * [OPENMEETINGS-540] - Uploading of .odt files
+    * [OPENMEETINGS-552] - Release blocking UI issues
+    * [OPENMEETINGS-561] - Video is not removed on Whiteboard closing
+    * [OPENMEETINGS-563] - "Black box" is displayed on test audio/video setup dialog
+    * [OPENMEETINGS-565] - Stackoverflow Exception when you goto your user profile and try to save it.
+    * [OPENMEETINGS-566] - No default timezone selection in registration/sign up when user is in timezone +12
+    * [OPENMEETINGS-567] - If you hit the "start upload" button twice, while the conversion is running, Openmeetings will run into an error
+    * [OPENMEETINGS-568] - OpenMeetings requests access to Cam even if there is none
+    * [OPENMEETINGS-569] - Faulty highperf settings in bat script
+    * [OPENMEETINGS-572] - Empty fields are replaced with string "null" after export&import
+    * [OPENMEETINGS-580] - Smslib 3.5.3 should be used.
+    * [OPENMEETINGS-582] - 2.0 RoomPoll and Configs restore failed
+
+** Improvement
+    * [OPENMEETINGS-93] - Create Openmeetings plug-in
+    * [OPENMEETINGS-119] - New users french manual
+    * [OPENMEETINGS-299] - Language import should be improved to take less time
+    * [OPENMEETINGS-339] - File location detection should be centralized
+    * [OPENMEETINGS-349] - OM should be scalable 
+    * [OPENMEETINGS-356] - Modify Rooms menu to have three options for each of the room types
+    * [OPENMEETINGS-357] - Users should first log into "Private rooms", have as a Admin selectable option for where users first log into
+    * [OPENMEETINGS-361] - It should be available to set logo in OM
+    * [OPENMEETINGS-384] - Mention that the file parameter is optional for the admin setup script
+    * [OPENMEETINGS-386] - Import/Export should be automatic based on Annotations
+    * [OPENMEETINGS-387] - It should be possible to create Appointment and use existent room
+    * [OPENMEETINGS-390] - Openmeetings Plugin for Bitrix need to be implemented
+    * [OPENMEETINGS-395] - Ability to add multiple external attendees should be added to the calendar
+    * [OPENMEETINGS-397] - Private chat with chat disabled
+    * [OPENMEETINGS-398] - Updated french translation for OM 2.1
+    * [OPENMEETINGS-399] - jitsi openmeetings plugin
+    * [OPENMEETINGS-400] - Improve volume slider
+    * [OPENMEETINGS-436] - Ability to moderate room chat should be added
+    * [OPENMEETINGS-470] - SIP meeting extensions
+    * [OPENMEETINGS-477] - Possibility to copy invitation link to the clipboard should be added
+    * [OPENMEETINGS-478] - It should be possible to enable auto videopod selection
+    * [OPENMEETINGS-480] - It would be better to remove confirmation dialog when user turns micro on/off.
+    * [OPENMEETINGS-497] - Confirmation diolog for the turning micro on/off is inconvenient.
+    * [OPENMEETINGS-501] - fresh build fails with class org/jdom/JDOMException not found in anakia build section
+    * [OPENMEETINGS-518] - Sms text sent as a meeting reminder is too long sometime.
+    * [OPENMEETINGS-527] - Confirm an exclusive audio
+    * [OPENMEETINGS-529] - AEC should be utilized in OM
+    * [OPENMEETINGS-535] - an update of the german language file
+    * [OPENMEETINGS-541] - Updated version of French language file
+    * [OPENMEETINGS-562] - To import ppt presentation delete page
+    * [OPENMEETINGS-583] - Ability to disable enhanced microphone should be added
+
+** New Feature
+    * [OPENMEETINGS-111] - Command line admin need to be created
+    * [OPENMEETINGS-342] - Private Chat should be available in the room
+    * [OPENMEETINGS-350] - Hot key should be added to be able to "rearrange" video windows in the room
+    * [OPENMEETINGS-351] - Add a possibility to send sms as an appointment reminder
+    * [OPENMEETINGS-354] - Volume slider
+    * [OPENMEETINGS-383] - Plugin for Joomla should be added to Openmeetings
+
+** Task
+    * [OPENMEETINGS-41] - OM without private storage area
+    * [OPENMEETINGS-107] - Unify database schema
+    * [OPENMEETINGS-248] - Remove LGPL Icons from Symbol/Cliparts and Emoticons
+    * [OPENMEETINGS-306] - Initial network quality test
+    * [OPENMEETINGS-341] - Update to portugues brasil Language
+    * [OPENMEETINGS-414] - Delete SIP Applet from stack
+    * [OPENMEETINGS-417] - How to add/register SIP extension in OpenMeeting ?
+    * [OPENMEETINGS-446] - Create a Master backup File for last versions (including all generated data)
+    * [OPENMEETINGS-522] - add Redmine Plugin Link to HomePage
+    * [OPENMEETINGS-585] - Clustering documentation
+
+** Test
+    * [OPENMEETINGS-50] - content of whiteboards
+
+
+Release Notes - OpenMeetings - Version 2.0-INCUBATING
+================================================================================================================
+** Sub-task
+    [OPENMEETINGS-8] - Generate CalendarAPI for SOAP/REST WebServices
+    [OPENMEETINGS-9] - Design MockUp for new Calendar UI
+    [OPENMEETINGS-40] - Merge Audio/Video components to trunk
+    [OPENMEETINGS-44] - remove all old audio/video components
+    [OPENMEETINGS-47] - fix ScopeApplicationAdapter / sync and message broadcasting mechanism to not send messages to SWF10 client
+    [OPENMEETINGS-51] - fix url params (invitationHash / secureHash / language_id / roomScopeId / et cetera ) to be forwarded to inner SWF components
+    [OPENMEETINGS-52] - fix icon status in new video components
+    [OPENMEETINGS-53] - Add security mechanism to LocalConnection subscribers
+    [OPENMEETINGS-54] - fix recorder to use new audio/video components and fix recording itself to reference correct streams
+    [OPENMEETINGS-55] - fix testing application (5 second video recording on room enter) to use new a/v components
+    [OPENMEETINGS-61] - fix screensharing player to use the new audio/video components
+    [OPENMEETINGS-62] - Clean up 5-second recordings using a scheduler
+    [OPENMEETINGS-65] - fix whiteboard video player to use the new audio/video components
+    [OPENMEETINGS-71] - fix interview room type to use new audio/video components
+    [OPENMEETINGS-73] - fix mute functionality in new video components
+    [OPENMEETINGS-77] - changeDevice.lzx must be transformed to SWF10
+    [OPENMEETINGS-79] - Share

<TRUNCATED>

[22/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] several minor issues are fixed

Posted by so...@apache.org.
[OPENMEETINGS-551] several minor issues are fixed


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/4e2f1275
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/4e2f1275
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/4e2f1275

Branch: refs/heads/master
Commit: 4e2f1275d0e782ca9f3e4dc569635d4745e2f231
Parents: 8599b3d
Author: Maxim Solodovnik <so...@apache.org>
Authored: Tue Apr 11 17:00:26 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Tue Apr 11 17:00:26 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/core/remote/MobileService.java |  3 ++
 .../apache/openmeetings/web/pages/HashPage.java | 36 +++++++++++---------
 .../apache/openmeetings/web/pages/MainPage.java | 11 +++---
 .../org/apache/openmeetings/web/room/wb/wb.js   | 34 +++++++++++++-----
 4 files changed, 54 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/4e2f1275/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
index cd13329..e2976c4 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
@@ -393,6 +393,9 @@ public class MobileService {
 	}
 
 	public void sendChatMessage(Client c, ChatMessage m, FastDateFormat fmt) {
+		if (c == null) {
+			return;
+		}
 		Map<String, Object> hsm = new HashMap<>();
 		hsm.put("client", c);
 		hsm.put("message", Arrays.asList("chat", encodeChatMessage(m, fmt)));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/4e2f1275/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
index 7c98592..8fa58ff 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
@@ -66,8 +66,27 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 	private boolean error = true;
 	private MainPanel mp = null;
 	private RoomPanel rp = null;
+	private final PageParameters p;
 
 	public HashPage(PageParameters p) {
+		this.p = p;
+	}
+
+	private void createRoom(Long roomId) {
+		error = false;
+		getHeader().setVisible(false);
+		// need to re-fetch Room object to initialize all collections
+		Room room = getBean(RoomDao.class).get(roomId);
+		if (room != null) {
+			rp = new RoomPanel(CHILD_ID, room);
+			mp = new MainPanel(PANEL_MAIN, rp);
+			replace(mp);
+		}
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
 		StringValue secure = p.get(HASH);
 		StringValue invitation = p.get(INVITATION_HASH);
 
@@ -124,23 +143,6 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 		}
 		add(recContainer.add(vi.setShowShare(false).setOutputMarkupPlaceholderTag(true),
 				vp.setOutputMarkupPlaceholderTag(true)), new InvitationPasswordDialog("i-pass", this));
-	}
-
-	private void createRoom(Long roomId) {
-		error = false;
-		getHeader().setVisible(false);
-		// need to re-fetch Room object to initialize all collections
-		Room room = getBean(RoomDao.class).get(roomId);
-		if (room != null) {
-			rp = new RoomPanel(CHILD_ID, room);
-			mp = new MainPanel(PANEL_MAIN, rp);
-			replace(mp);
-		}
-	}
-
-	@Override
-	protected void onInitialize() {
-		super.onInitialize();
 		remove(urlParametersReceivingBehavior);
 		add(new MessageDialog("access-denied", getString("invalid.hash"), getString(errorKey), DialogButtons.OK,
 				DialogIcon.ERROR) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/4e2f1275/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java
index 8e16e17..cdbd0e0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java
@@ -41,12 +41,13 @@ import org.apache.wicket.util.time.Duration;
 @AuthorizeInstantiation({"Admin", "Dashboard", "Room"})
 public class MainPage extends BaseInitedPage {
 	private static final long serialVersionUID = 1L;
-	private final AbstractAjaxTimerBehavior areaBehavior;
+	private AbstractAjaxTimerBehavior areaBehavior;
 	private final MainPanel main = new MainPanel("main");
-	private final InviteUserToRoomDialog inviteUser;
+	private InviteUserToRoomDialog inviteUser;
 
-	public MainPage() {
-		super();
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
 		getHeader().setVisible(false);
 		add(main, inviteUser = new InviteUserToRoomDialog("invite-to-room"));
 		//load preselected content
@@ -68,7 +69,7 @@ public class MainPage extends BaseInitedPage {
 			protected void respond(AjaxRequestTarget target) {
 				inviteUser.open(target, getParam(getComponent(), PARAM_USER_ID).toLong());
 			}
-			
+
 			@Override
 			public void renderHead(Component component, IHeaderResponse response) {
 				super.renderHead(component, response);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/4e2f1275/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index f580f19..61f1c0c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -154,6 +154,7 @@ var APointer = function(wb) {
 	}
 	pointer.activate = function() {
 		wb.eachCanvas(function(canvas) {
+			canvas.selection = false;
 			canvas.on('mouse:up', pointer.mouseUp);
 		});
 		pointer.user = $('.room.sidebar.left .user.list .current .name').text();
@@ -681,13 +682,16 @@ var Wb = function() {
 	}
 	function _modifyHandler(_o) {
 		_removeHandler(_o);
-		canvases[_o.slide].add(_o);
+		var canvas = canvases[_o.slide];
+		_o.selectable = canvas.selection;
+		canvas.add(_o);
 	}
 	function _createHandler(_o) {
 		switch (_o.fileType) {
 			case 'Video':
 			case 'Recording':
 			{
+				var canvas = canvases[_o.slide];
 				var vid = $('<video>').hide().attr('id', 'video-' + _o.uid).attr('poster', _o._poster + '&preview=true')
 					.attr("width", _o.width).attr("height", _o.height)
 					.append($('<source>').attr('type', 'video/mp4').attr('src', _o._src))
@@ -696,7 +700,8 @@ var Wb = function() {
 					left: _o.left
 					, top: _o.top
 				});
-				canvases[_o.slide].add(vImg);
+				vImg.selectable = canvas.selection;
+				canvas.add(vImg);
 				//console.log(vImg.toJSON(['uid', 'fileId', 'fileType']));
 			}
 				break;
@@ -726,7 +731,11 @@ var Wb = function() {
 			}
 				break;
 			default:
-				canvases[_o.slide].add(_o);
+			{
+				var canvas = canvases[_o.slide];
+				_o.selectable = canvas.selection;
+				canvas.add(_o);
+			}
 				break;
 		}
 	}
@@ -754,6 +763,8 @@ var Wb = function() {
 	}
 	//events
 	function wbObjCreatedHandler(o) {
+		if (readOnly && o.type != 'pointer') return;
+
 		var json = {};
 		switch(o.type) {
 			case 'pointer':
@@ -778,10 +789,15 @@ var Wb = function() {
 				o.slide = this.slide;
 				wbObjCreatedHandler(o);
 				break;
+			default:
+				o.selectable = this.selection;
+				break;
 		}
 	};
 	function objModifiedHandler(e) {
 		var o = e.target;
+		if (readOnly && o.type != 'pointer') return;
+
 		o.includeDefaultValues = false;
 		wbAction('modifyObj', JSON.stringify({
 			wbId: wb.id
@@ -838,25 +854,25 @@ var Wb = function() {
 		console.log('Text Changed', obj);
 	};*/
 	function setHandlers(canvas) {
+		canvas.on({
+			'wb:object:created': wbObjCreatedHandler
+			, 'object:modified': objModifiedHandler
+		});
 		if (readOnly) {
 			canvas.off({
 				'object:added': objAddedHandler
-				, 'object:modified': objModifiedHandler
 				, 'object:selected': objSelectedHandler
 				, 'path:created': pathCreatedHandler
 				//, 'text:editing:exited': textEditedHandler
 				//, 'text:changed': textChangedHandler
-				, 'wb:object:created': wbObjCreatedHandler
 			});
 		} else {
 			canvas.on({
 				'object:added': objAddedHandler
-				, 'object:modified': objModifiedHandler
 				, 'object:selected': objSelectedHandler
 				, 'path:created': pathCreatedHandler
 				//, 'text:editing:exited': textEditedHandler
 				//, 'text:changed': textChangedHandler
-				, 'wb:object:created': wbObjCreatedHandler
 			});
 		}
 	}
@@ -865,7 +881,9 @@ var Wb = function() {
 		var cid = 'can-' + a.attr('id') + '-slide-' + sl;
 		var c = $('<canvas></canvas>').attr('id', cid);
 		a.find('.canvases').append(c);
-		var canvas = new fabric.Canvas(c.attr('id'));
+		var canvas = new fabric.Canvas(c.attr('id'), {
+			preserveObjectStacking: true
+		});
 		canvas.wbId = wb.id;
 		canvas.slide = sl;
 		canvases.push(canvas);


[45/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] fallback handling and volume slider are added

Posted by so...@apache.org.
[OPENMEETINGS-551] fallback handling and volume slider are added


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/a600e321
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/a600e321
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/a600e321

Branch: refs/heads/master
Commit: a600e321f9dd4ccc8a1efe3cd7f2bb8ccf0877f0
Parents: a4d2a56
Author: Maxim Solodovnik <so...@apache.org>
Authored: Fri Apr 21 01:27:01 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Fri Apr 21 01:27:01 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/db/entity/basic/Client.java    | 11 ++++--
 .../flex/org/apache/openmeetings/OmVideo.as     | 37 ++++++++++++--------
 .../apache/openmeetings/web/room/RoomPanel.html | 12 +++++++
 .../apache/openmeetings/web/room/RoomPanel.java | 29 ++++++++++-----
 .../org/apache/openmeetings/web/room/room.js    | 24 +++++++++++++
 .../web/room/sidebar/RoomSidebar.java           |  2 +-
 openmeetings-web/src/main/webapp/css/room.css   | 14 +++++++-
 7 files changed, 102 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a600e321/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
index 0f8fc82..19e9787 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
@@ -342,7 +342,7 @@ public class Client implements IClient {
 		return true;
 	}
 
-	public JSONObject toJson() {
+	public JSONObject toJson(boolean self) {
 		JSONObject u = new JSONObject();
 		if (user != null) {
 			JSONObject a = new JSONObject();
@@ -356,7 +356,7 @@ public class Client implements IClient {
 				a.put("country", user.getAddress().getCountry());
 			}
 		}
-		return new JSONObject()
+		JSONObject json = new JSONObject()
 				.put("user", u)
 				.put("uid", uid)
 				.put("rights", new JSONArray(rights))
@@ -364,7 +364,12 @@ public class Client implements IClient {
 				.put("pod", pod)
 				.put("broadcastId", broadcastId)
 				.put("width", width)
-				.put("height", height);
+				.put("height", height)
+				.put("self", self);
+		if (self) {
+			json.put("cam", cam).put("mic", mic);
+		}
+		return json;
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a600e321/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
index 5538f46..c32e8a2 100644
--- a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
+++ b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
@@ -45,6 +45,7 @@ public class OmVideo {
 	public var height:int;
 	private var mode:String;
 	private var params:Object;
+	private var url:String;
 	private var fallback:Boolean;
 
 	public function OmVideo(ui:UIComponent, params:Object) {
@@ -97,9 +98,6 @@ public class OmVideo {
 	private function createStream():void {
 		debug("createStream: ");
 		ns = new NetStream(nc);
-		//see: http://livedocs.adobe.com/flash/9.0_de/ActionScriptLangRefV3/flash/net/NetStream.html
-		//according to the docs the construct to catch event has to be implemented like this.
-		//var t = this;
 		ns.client = {
 			onMetaData: function(metadata:Object):void {
 				debug("onMetaData: ", metadata);
@@ -137,7 +135,6 @@ public class OmVideo {
 
 		if (cam != null) {
 			ns.attachCamera(cam);
-			//invokes Method in baseVideoView which shows the cam
 			attachCamera(cam);
 
 			var videoStreamSettings:VideoStreamSettings = null;
@@ -166,17 +163,33 @@ public class OmVideo {
 		}
 	}
 
+	private function _connect(url:String):void {
+		nc.connect(url, {
+			uid: params.uid
+			, sid: params.sid
+			, nativeSsl: 'best' == params.proxyType
+		});
+	}
+
 	private function connect(callback:Function):void {
 		if (nc == null || !nc.connected) {
-			var url:String = params.url;  //TODO fallback
+			url = params.url;
 			debug("NetConnection is not connected", url);
 			nc = new NetConnection();
 			nc.addEventListener(NetStatusEvent.NET_STATUS, function onConnectionStatus(e:NetStatusEvent):void {
 				debug("ConnectionStatus: " + e.info.code);
-				if (e.info.code == "NetConnection.Connect.Success") {
-					callback();
-				} else {
-					//TODO
+				switch (e.info.code) {
+					case 'NetConnection.Connect.Failed':
+						if (!fallback) {
+							fallback = true;
+							url = params.fallback;
+							_connect(url);
+						}
+						break;
+					case 'NetConnection.Connect.Success':
+						callback();
+						break;
+					//TODO other cases
 				}
 			});
 			nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, function (event:AsyncErrorEvent):void {
@@ -197,11 +210,7 @@ public class OmVideo {
 					debug("id: " + id); //TODO save connection id
 				}
 			};
-			nc.connect(url, {
-				uid: params.uid
-				, sid: params.sid
-				, nativeSsl: 'best' == params.proxyType
-			});
+			_connect(url);
 		} else {
 			callback();
 		}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a600e321/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
index 87afb87..3f30083 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
@@ -46,6 +46,18 @@
 		<div id="user-video">
 			<div class="video"></div>
 		</div>
+		<div id="video-volume-btn">
+			<a class="ui-dialog-titlebar-volume ui-corner-all ui-state-default" href="#" title="volume" role="button" data-toggle="dropdown">
+				<span class="ui-icon ui-icon-triangle-2-n-s">volume</span>
+			</a>
+			<ul class="dropdown-menu video volume">
+				<li>
+					<div class="slider">
+						<div class="ui-slider-handle handle"></div>
+					</div>
+				</li>
+			</ul>
+		</div>
 	</div>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a600e321/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 315acc0..0cf02f3 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -161,7 +161,7 @@ public class RoomPanel extends BasePanel {
 		for (Client c: getRoomClients(getRoom().getId()) ){
 			boolean self = getClient().getUid().equals(c.getUid());
 			if (!self) {
-				JSONObject json = c.toJson().put("sid", getSid()).put("self", self);
+				JSONObject json = c.toJson(self).put("sid", getSid());
 				// TODO we should check if client is screenShare, see onEvent newStream case.
 				target.appendJavaScript(String.format("VideoManager.play(%s);", json));
 			}
@@ -344,7 +344,7 @@ public class RoomPanel extends BasePanel {
 								log.error("Not existing user has stopped recording {} !!!!", uid);
 								return;
 							}
-							c.getActivities().remove(Client.Activity.record);
+							c.remove(Client.Activity.record);
 						}
 						break;
 					case recordingStarted:
@@ -356,17 +356,30 @@ public class RoomPanel extends BasePanel {
 								log.error("Not existing user has started recording {} !!!!", recordingUser);
 								return;
 							}
-							c.getActivities().add(Client.Activity.record);
+							c.set(Client.Activity.record);
 						}
 						break;
 					case sharingStoped:
-						//TODO check sharingUser == ((TextRoomMessage)m).getText();
-						sharingUser = null;
-						menu.update(handler);
+						{
+							sharingUser = null;
+							Client c = getOnlineClient(((TextRoomMessage)m).getText());
+							if (c == null) {
+								log.error("Not existing user has started sharing {} !!!!", sharingUser);
+								return;
+							}
+							c.remove(Client.Activity.share);
+							menu.update(handler);
+						}
 						break;
 					case sharingStarted:
 						{
 							sharingUser = ((TextRoomMessage)m).getText();
+							Client c = getOnlineClient(sharingUser);
+							if (c == null) {
+								log.error("Not existing user has started sharing {} !!!!", sharingUser);
+								return;
+							}
+							c.set(Client.Activity.share);
 							menu.update(handler);
 						}
 						break;
@@ -374,7 +387,7 @@ public class RoomPanel extends BasePanel {
 						{
 							Client c = getOnlineClient(((TextRoomMessage)m).getText());
 							handler.appendJavaScript(String.format("VideoManager.update(%s);"
-									, c.toJson().put("sid", getSid()).put("self", getClient().getUid().equals(c.getUid()))));
+									, c.toJson(getClient().getUid().equals(c.getUid())).put("sid", getSid())));
 							sidebar.update(handler);
 							menu.update(handler);
 							wb.update(handler);
@@ -386,7 +399,7 @@ public class RoomPanel extends BasePanel {
 						Client c = getOnlineClient(obj.getString("uid"));
 						boolean self = getClient().getUid().equals(c.getUid());
 						if (!self) {
-							JSONObject json = c.toJson().put("sid", getSid()).put("self", self);
+							JSONObject json = c.toJson(self).put("sid", getSid());
 							if (obj.optBoolean("screenShare", false)) {
 								json.put("screenShare", true)
 									.put("uid", obj.getString("suid")) // unique screen-sharing ID

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a600e321/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index cd182c0..1b2d687 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -63,6 +63,30 @@ var Video = (function() {
 			, dblclick: "collapse"
 		});
 		t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
+		v.parent().find('.ui-dialog-titlebar-buttonpane').append($('#video-volume-btn').children().clone());
+		var volume = v.parent().find('.dropdown-menu.video.volume');
+		v.parent().find('.ui-dialog-titlebar-volume').click(function(e) {
+			e.stopImmediatePropagation();
+			volume.toggle();
+		}).dblclick(function(e) {
+			e.stopImmediatePropagation();
+		});
+		var handle = v.parent().find('.slider .handle');
+		v.parent().find('.slider').slider({
+			orientation: 'vertical'
+			, range: 'min'
+			, min: 0
+			, max: 100
+			, value: 60
+			, slide: function(event, ui) {
+			}
+			, create: function() {
+				handle.text($(this).slider("value"));
+			}
+			, slide: function(event, ui) {
+				handle.text(ui.value);
+			}
+		});
 		vc = v.find('.video');
 		vc.width(_w).height(_h);
 		//broadcast

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a600e321/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index 168bea9..17b6973 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -414,7 +414,7 @@ public class RoomSidebar extends Panel {
 			}
 			Pod pod = c.getPod();
 			c.setPod(getRequest().getRequestParameters().getParameterValue(PARAM_POD).toOptionalInteger());
-			if (pod != Pod.none && pod != c.getPod()) {
+			if (pod != null && pod != Pod.none && pod != c.getPod()) {
 				//pod has changed, no need to toggle
 				c.set(a);
 			} else {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a600e321/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index 04d3a2b..cf437c1 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -354,10 +354,22 @@
 }
 .ui-dialog.video, .ui-dialog.video .ui-dialog-titlebar, .ui-dialog.video .ui-dialog-content {
 	padding: 0;
+}
+.ui-dialog.video .ui-dialog-content {
 	overflow: hidden;
 }
 .ui-dialog.video .ui-dialog-titlebar {
-	padding-left:10px
+	padding-left: 10px
+}
+.dropdown-menu.video.volume, .dropdown-menu.video.volume li {
+	width: 20px;
+	min-width: 20px;
+	border-radius: 0;
+	border: 0;
+	box-shadow: initial;
+	left: 50px;
+	top: -50px;
+	background-color: transparent;
 }
 .ui-dialog.video .title {
 	font-weight: bold;


[06/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] add/remove readOnly is added to WB

Posted by so...@apache.org.
[OPENMEETINGS-551] add/remove readOnly is added to WB


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/7859e815
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/7859e815
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/7859e815

Branch: refs/heads/master
Commit: 7859e8152d3479f4642e557de2bfe66d3811e446
Parents: 89b00fd
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 2 12:24:13 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 2 12:24:13 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/web/room/wb/WbPanel.html       | 108 +++---
 .../openmeetings/web/room/wb/WbPanel.java       |   2 +-
 .../org/apache/openmeetings/web/room/wb/wb.js   | 353 ++++++++++++-------
 openmeetings-web/src/main/webapp/css/room.css   |   8 +
 4 files changed, 292 insertions(+), 179 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7859e815/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
index c0a8ddc..7857c41 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.html
@@ -22,23 +22,26 @@
 <wicket:panel>
 	<div class="tabs">
 		<div class="wb-tabbar ui-corner-all ui-widget-header">
-			<div class="add clickable om-icon big"></div>
-			<div class="prev clickable om-icon big"></div>
 			<div class="scroll-container"><ul class="scrollable"></ul></div>
-			<div class="next clickable om-icon big"></div>
 		</div>
 	</div>
 
 	<div style="display:none;">
+		<div id="wb-tabbar-ctrls-left">
+			<div class="add clickable om-icon big"></div>
+			<div class="prev clickable om-icon big"></div>
+		</div>
+		<div id="wb-tabbar-ctrls-right">
+			<div class="next clickable om-icon big"></div>
+		</div>
 		<ul><li id="wb-area-tab">
 			<a>[title]</a>
-			<button type="button" class="ui-button ui-corner-all ui-widget ui-button-icon-only ui-dialog-titlebar-close" wicket:message="title:85">
-				<span class="ui-button-icon ui-icon ui-icon-closethick"></span>
-				<span class="ui-button-icon-space"> </span>
-				<wicket:message key="85"/>
-			</button>
 		</li></ul>
-	
+		<button id="wb-tab-close" type="button" class="ui-button ui-corner-all ui-widget ui-button-icon-only ui-dialog-titlebar-close" wicket:message="title:85">
+			<span class="ui-button-icon ui-icon ui-icon-closethick"></span>
+			<span class="ui-button-icon-space"> </span>
+			<wicket:message key="85"/>
+		</button>
 		<div id="wb-area-cliparts" class="btn-group" style="float: left;">
 			<a class="dropdown-toggle" data-toggle="dropdown" wicket:message="title:1323"></a>
 			<ul class="dropdown-menu om-left">
@@ -48,54 +51,57 @@
 				</li>
 			</ul>
 		</div>
-		
 		<div id="wb-area">
 			<div class="scroll-container">
 				<div class="canvases"></div>
 			</div>
-			<div class="tools ui-state-active vertical clear" style="position: absolute; top: 20px; right: 0px;">
-				<div class="bumper"></div>
-				<div wicket:message="title:72" class="ui-widget-header clickable om-icon big pointer"></div>
-				<div wicket:message="title:557" class="ui-widget-header clickable om-icon big apointer"></div>
-				<div wicket:message="title:73" class="ui-widget-header clickable om-icon big text"></div>
-				<div wicket:message="title:74" class="ui-widget-header clickable om-icon big paint"></div>
-				<div wicket:message="title:75" class="ui-widget-header clickable om-icon big line"></div>
-				<div wicket:message="title:76" class="ui-widget-header clickable om-icon big uline"></div>
-				<div wicket:message="title:77" class="ui-widget-header clickable om-icon big rect"></div>
-				<div wicket:message="title:78" class="ui-widget-header clickable om-icon big ellipse"></div>
-				<div wicket:message="title:79" class="ui-widget-header clickable om-icon big arrow"></div>
-				<div wicket:message="title:4" class="ui-widget-header clickable om-icon big settings"></div>
+		</div>
+		<div id="wb-tools" class="tools ui-state-active vertical clear" style="position: absolute; top: 20px; right: 0px;">
+			<div class="bumper"></div>
+			<div wicket:message="title:72" class="ui-widget-header clickable om-icon big pointer"></div>
+			<div wicket:message="title:557" class="ui-widget-header clickable om-icon big apointer"></div>
+			<div wicket:message="title:73" class="ui-widget-header clickable om-icon big text"></div>
+			<div wicket:message="title:74" class="ui-widget-header clickable om-icon big paint"></div>
+			<div wicket:message="title:75" class="ui-widget-header clickable om-icon big line"></div>
+			<div wicket:message="title:76" class="ui-widget-header clickable om-icon big uline"></div>
+			<div wicket:message="title:77" class="ui-widget-header clickable om-icon big rect"></div>
+			<div wicket:message="title:78" class="ui-widget-header clickable om-icon big ellipse"></div>
+			<div wicket:message="title:79" class="ui-widget-header clickable om-icon big arrow"></div>
+			<div wicket:message="title:4" class="ui-widget-header clickable om-icon big settings"></div>
+		</div>
+		<div id="wb-tools-readonly" class="tools readonly ui-state-active vertical clear" style="position: absolute; top: 20px; right: 0px;">
+			<div class="bumper"></div>
+			<div wicket:message="title:557" class="ui-widget-header clickable om-icon big apointer"></div>
+		</div>
+		<div id="wb-settings" class="wb-settings ui-corner-all ui-widget-content" style="display: none; bottom: 100px; right: 100px;">
+			<div wicket:message="title:843" class="header ui-dialog-titlebar ui-corner-all ui-widget-header ui-helper-clearfix ui-draggable-handle">
+				<span class="ui-dialog-title"><wicket:message key="843"/></span>
+				<button type="button" class="ui-button ui-corner-all ui-widget ui-button-icon-only ui-dialog-titlebar-close" wicket:message="title:85">
+					<span class="ui-button-icon ui-icon ui-icon-closethick"></span>
+					<span class="ui-button-icon-space"> </span>
+					<wicket:message key="85"/>
+				</button>
 			</div>
-			<div class="wb-settings ui-corner-all ui-widget-content" style="display: none; bottom: 100px; right: 100px;">
-				<div wicket:message="title:843" class="header ui-dialog-titlebar ui-corner-all ui-widget-header ui-helper-clearfix ui-draggable-handle">
-					<span class="ui-dialog-title"><wicket:message key="843"/></span>
-					<button type="button" class="ui-button ui-corner-all ui-widget ui-button-icon-only ui-dialog-titlebar-close" wicket:message="title:85">
-						<span class="ui-button-icon ui-icon ui-icon-closethick"></span>
-						<span class="ui-button-icon-space"> </span>
-						<wicket:message key="85"/>
-					</button>
+			<div class="tab props">
+				<div class="prop-row">
+					<div class="block lbl" wicket:message="title:546"><wicket:message key="545"/></div>
+					<div class="block input"><input class="wb-dim-x" type="text" maxlength="4" readonly="readonly"/></div>
+					<div class="block lbl" wicket:message="title:550"><wicket:message key="549"/></div>
+					<div class="block input"><input class="wb-dim-w" type="text" maxlength="4" readonly="readonly"/></div>
+					<div class="block input" style="width: 2em;"><input class="wb-prop-color" type="color" value="#ff6600" wicket:message="title:424"/></div>
+					<div class="block but"><button class="wb-prop-lock-color" wicket:message="title:426">&nbsp;</button></div>
+					<div class="block input"><input class="wb-prop-width" type="number" min="1" max="100" value="2" wicket:message="title:429"/></div>
+					<div class="block but"><button class="wb-prop-i" wicket:message="title:86">I</button></div>
 				</div>
-				<div class="tab props">
-					<div class="prop-row">
-						<div class="block lbl" wicket:message="title:546"><wicket:message key="545"/></div>
-						<div class="block input"><input class="wb-dim-x" type="text" maxlength="4" readonly="readonly"/></div>
-						<div class="block lbl" wicket:message="title:550"><wicket:message key="549"/></div>
-						<div class="block input"><input class="wb-dim-w" type="text" maxlength="4" readonly="readonly"/></div>
-						<div class="block input" style="width: 2em;"><input class="wb-prop-color" type="color" value="#ff6600" wicket:message="title:424"/></div>
-						<div class="block but"><button class="wb-prop-lock-color" wicket:message="title:426">&nbsp;</button></div>
-						<div class="block input"><input class="wb-prop-width" type="number" min="1" max="100" value="2" wicket:message="title:429"/></div>
-						<div class="block but"><button class="wb-prop-i" wicket:message="title:86">I</button></div>
-					</div>
-					<div class="prop-row">
-						<div class="block lbl" wicket:message="title:548"><wicket:message key="547"/></div>
-						<div class="block input"><input class="wb-dim-y" type="text" maxlength="4" readonly="readonly"/></div>
-						<div class="block lbl" wicket:message="title:552"><wicket:message key="551"/></div>
-						<div class="block input"><input class="wb-dim-h" type="text" maxlength="4" readonly="readonly"/></div>
-						<div class="block input" style="width: 2em;"><input class="wb-prop-fill" type="color" value="#ffff33" wicket:message="title:427"/></div>
-						<div class="block but"><button class="wb-prop-lock-fill" wicket:message="title:428">&nbsp;</button></div>
-						<div class="block input"><input class="wb-prop-opacity" type="number" min="1" max="100" value="100" wicket:message="title:553"/></div>
-						<div class="block but"><button class="wb-prop-b" wicket:message="title:87">B</button></div>
-					</div>
+				<div class="prop-row">
+					<div class="block lbl" wicket:message="title:548"><wicket:message key="547"/></div>
+					<div class="block input"><input class="wb-dim-y" type="text" maxlength="4" readonly="readonly"/></div>
+					<div class="block lbl" wicket:message="title:552"><wicket:message key="551"/></div>
+					<div class="block input"><input class="wb-dim-h" type="text" maxlength="4" readonly="readonly"/></div>
+					<div class="block input" style="width: 2em;"><input class="wb-prop-fill" type="color" value="#ffff33" wicket:message="title:427"/></div>
+					<div class="block but"><button class="wb-prop-lock-fill" wicket:message="title:428">&nbsp;</button></div>
+					<div class="block input"><input class="wb-prop-opacity" type="number" min="1" max="100" value="100" wicket:message="title:553"/></div>
+					<div class="block but"><button class="wb-prop-b" wicket:message="title:87">B</button></div>
 				</div>
 			</div>
 		</div>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7859e815/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index 2375130..c446ead 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -272,7 +272,7 @@ public class WbPanel extends Panel {
 	public WbPanel update(IPartialPageRequestHandler handler) {
 		readOnly = !rp.getClient().hasRight(Right.whiteBoard);
 		if (handler != null) {
-			handler.appendJavaScript("setRoomSizes();");
+			handler.appendJavaScript(String.format("setRoomSizes();WbArea.setReadOnly(%s);", readOnly));
 		}
 		return this;
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7859e815/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index 57f6943..64ee00d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -484,10 +484,10 @@ var Wb = function() {
 	const ACTIVE = 'active';
 	const BUMPER = 100;
 	var wb = {id: -1}, a, t, s, canvases = [], mode, slide = 0, width = 0, height = 0
-			, minWidth = 0, minHeight = 0;
+			, minWidth = 0, minHeight = 0, readOnly = null;
 
 	function getBtn(m) {
-		return t.find(".om-icon." + (m || mode));
+		return !!t ? t.find(".om-icon." + (m || mode)) : null;
 	}
 	function initToolBtn(m, def, obj) {
 		var btn = getBtn(m);
@@ -530,7 +530,7 @@ var Wb = function() {
 			initToolBtn(cur.data('mode'), false, Clipart(wb, cur));
 		});
 	}
-	function internalInit(t) {
+	function internalInit() {
 		t.draggable({
 			snap: "parent"
 			, containment: "parent"
@@ -544,88 +544,92 @@ var Wb = function() {
 				}
 			}
 		});
-		initToolBtn('pointer', true, Pointer(wb, s));
-		initToolBtn('apointer', false, APointer(wb));
-		initToolBtn('text', false, Text(wb, s));
-		initToolBtn('paint', false, Paint(wb, s));
-		initToolBtn('line', false, Line(wb, s));
-		initToolBtn('uline', false, ULine(wb, s));
-		initToolBtn('rect', false, Rect(wb, s));
-		initToolBtn('ellipse', false, Ellipse(wb, s));
-		initToolBtn('arrow', false, Arrow(wb, s));
-		initCliparts();
-		t.find(".om-icon.settings").click(function() {
-			s.show();
-		});
-		s.find('.wb-prop-b, .wb-prop-i')
-			.button()
-			.click(function() {
-				$(this).toggleClass('ui-state-active selected');
+		if (readOnly) {
+			initToolBtn('apointer', true, APointer(wb));
+		} else {
+			initToolBtn('pointer', true, Pointer(wb, s));
+			initToolBtn('apointer', false, APointer(wb));
+			initToolBtn('text', false, Text(wb, s));
+			initToolBtn('paint', false, Paint(wb, s));
+			initToolBtn('line', false, Line(wb, s));
+			initToolBtn('uline', false, ULine(wb, s));
+			initToolBtn('rect', false, Rect(wb, s));
+			initToolBtn('ellipse', false, Ellipse(wb, s));
+			initToolBtn('arrow', false, Arrow(wb, s));
+			initCliparts();
+			t.find(".om-icon.settings").click(function() {
+				s.show();
 			});
-		s.find('.wb-prop-lock-color, .wb-prop-lock-fill')
-			.button({icon: 'ui-icon-locked', showLabel: false})
-			.click(function() {
+			s.find('.wb-prop-b, .wb-prop-i')
+				.button()
+				.click(function() {
+					$(this).toggleClass('ui-state-active selected');
+				});
+			s.find('.wb-prop-lock-color, .wb-prop-lock-fill')
+				.button({icon: 'ui-icon-locked', showLabel: false})
+				.click(function() {
+					var btn = getBtn();
+					var isColor = $(this).hasClass('wb-prop-lock-color');
+					var c = s.find(isColor ? '.wb-prop-color' : '.wb-prop-fill');
+					var enabled = $(this).button('option', 'icon') == 'ui-icon-locked';
+					$(this).button('option', 'icon', enabled ? 'ui-icon-unlocked' : 'ui-icon-locked');
+					c.prop('disabled', !enabled);
+					btn.data('obj')[isColor ? 'stroke' : 'fill'].enabled = enabled;
+				});
+			s.find('.wb-prop-color').change(function() {
 				var btn = getBtn();
-				var isColor = $(this).hasClass('wb-prop-lock-color');
-				var c = s.find(isColor ? '.wb-prop-color' : '.wb-prop-fill');
-				var enabled = $(this).button('option', 'icon') == 'ui-icon-locked';
-				$(this).button('option', 'icon', enabled ? 'ui-icon-unlocked' : 'ui-icon-locked');
-				c.prop('disabled', !enabled);
-				btn.data('obj')[isColor ? 'stroke' : 'fill'].enabled = enabled;
-			});
-		s.find('.wb-prop-color').change(function() {
-			var btn = getBtn();
-			if (btn.length == 1) {
-				var v = $(this).val();
-				btn.data('obj').stroke.color = v;
-				if ('paint' == mode) {
-					wb.eachCanvas(function(canvas) {
-						canvas.freeDrawingBrush.color = v;
-					});
+				if (btn.length == 1) {
+					var v = $(this).val();
+					btn.data('obj').stroke.color = v;
+					if ('paint' == mode) {
+						wb.eachCanvas(function(canvas) {
+							canvas.freeDrawingBrush.color = v;
+						});
+					}
 				}
-			}
-		});
-		s.find('.wb-prop-width').change(function() {
-			var btn = getBtn();
-			if (btn.length == 1) {
-				var v = 1 * $(this).val();
-				btn.data('obj').stroke.width = v;
-				if ('paint' == mode) {
-					wb.eachCanvas(function(canvas) {
-						canvas.freeDrawingBrush.width = v;
-					});
+			});
+			s.find('.wb-prop-width').change(function() {
+				var btn = getBtn();
+				if (btn.length == 1) {
+					var v = 1 * $(this).val();
+					btn.data('obj').stroke.width = v;
+					if ('paint' == mode) {
+						wb.eachCanvas(function(canvas) {
+							canvas.freeDrawingBrush.width = v;
+						});
+					}
 				}
-			}
-		});
-		s.find('.wb-prop-opacity').change(function() {
-			var btn = getBtn();
-			if (btn.length == 1) {
-				var v = (1 * $(this).val()) / 100;
-				btn.data('obj').opacity = v;
-				if ('paint' == mode) {
-					wb.eachCanvas(function(canvas) {
-						canvas.freeDrawingBrush.opacity = v;
-					});
+			});
+			s.find('.wb-prop-opacity').change(function() {
+				var btn = getBtn();
+				if (btn.length == 1) {
+					var v = (1 * $(this).val()) / 100;
+					btn.data('obj').opacity = v;
+					if ('paint' == mode) {
+						wb.eachCanvas(function(canvas) {
+							canvas.freeDrawingBrush.opacity = v;
+						});
+					}
 				}
-			}
-		});
-		s.find('.ui-dialog-titlebar-close').click(function() {
-			s.hide();
-		});
-		s.draggable({
-			scroll: false
-			, containment: "body"
-			, start: function(event, ui) {
-				if (!!s.css("bottom")) {
-					s.css("bottom", "").css("right", "");
+			});
+			s.find('.ui-dialog-titlebar-close').click(function() {
+				s.hide();
+			});
+			s.draggable({
+				scroll: false
+				, containment: "body"
+				, start: function(event, ui) {
+					if (!!s.css("bottom")) {
+						s.css("bottom", "").css("right", "");
+					}
 				}
-			}
-			, drag: function(event, ui) {
-				if (s.position().x + s.width() >= s.parent().width()) {
-					return false;
+				, drag: function(event, ui) {
+					if (s.position().x + s.width() >= s.parent().width()) {
+						return false;
+					}
 				}
-			}
-		});
+			});
+		}
 	}
 	function _findObject(o) {
 		var _o = {};
@@ -756,6 +760,34 @@ var Wb = function() {
 		o.path.slide = this.slide;
 		wbObjCreatedHandler(o.path);
 	};
+	function scrollHandler(e) {
+		$(this).find('.canvas-container').each(function(idx) {
+			var h = $(this).height(), pos = $(this).position();
+			if (slide != idx &&pos.top > BUMPER - h && pos.top < BUMPER) {
+				//TODO FIXME might be done without iterating
+				//console.log("Found:", idx);
+				slide = idx;
+				wbAction('setSlide', JSON.stringify({
+					wbId: wb.id
+					, slide: idx
+				}));
+				return false;
+			}
+		});
+	}
+	function showCurentSlide() {
+		a.find('.scroll-container .canvas-container').each(function(idx) {
+			if (readOnly) {
+				if (idx == slide) {
+					$(this).show();
+				} else {
+					$(this).hide();
+				}
+			} else {
+				$(this).show();
+			}
+		});
+	}
 	/*TODO interactive text chage
 	var textEditedHandler = function (e) {
 		var obj = e.target;
@@ -766,45 +798,75 @@ var Wb = function() {
 		console.log('Text Changed', obj);
 	};*/
 	function addCanvas() {
-		var slide = canvases.length;
-		var c = $('<canvas></canvas>').attr('id', 'can-' + a.attr('id') + '-slide-' + slide);
+		var sl = canvases.length;
+		var cid = 'can-' + a.attr('id') + '-slide-' + sl;
+		var c = $('<canvas></canvas>').attr('id', cid);
 		a.find('.canvases').append(c);
 		var canvas = new fabric.Canvas(c.attr('id'));
 		canvas.wbId = wb.id;
-		canvas.slide = slide;
-		//TODO create via WS canvas:cleared
-		canvas.on({
-			'object:added': objAddedHandler
-			, 'object:modified': objModifiedHandler
-			, 'object:selected': objSelectedHandler
-			, 'path:created': pathCreatedHandler
-			//, 'text:editing:exited': textEditedHandler
-			//, 'text:changed': textChangedHandler
-			, 'wb:object:created': wbObjCreatedHandler
-		});
+		canvas.slide = sl;
 		canvases.push(canvas);
+		//TODO create via WS canvas:cleared
+		if (readOnly) {
+			canvas.off({
+				'object:added': objAddedHandler
+				, 'object:modified': objModifiedHandler
+				, 'object:selected': objSelectedHandler
+				, 'path:created': pathCreatedHandler
+				//, 'text:editing:exited': textEditedHandler
+				//, 'text:changed': textChangedHandler
+				, 'wb:object:created': wbObjCreatedHandler
+			});
+		} else {
+			canvas.on({
+				'object:added': objAddedHandler
+				, 'object:modified': objModifiedHandler
+				, 'object:selected': objSelectedHandler
+				, 'path:created': pathCreatedHandler
+				//, 'text:editing:exited': textEditedHandler
+				//, 'text:changed': textChangedHandler
+				, 'wb:object:created': wbObjCreatedHandler
+			});
+		}
+		var cc = $('#' + cid).closest('.canvas-container');
+		if (readOnly) {
+			if (sl == slide) {
+				cc.show();
+			} else {
+				cc.hide();
+			}
+		}
 	}
-	wb.init = function(_wbId, tid) {
+	wb.setReadOnly = function(ro) {
+		if (readOnly != ro) {
+			var btn = getBtn();
+			if (!!btn && btn.length == 1) {
+				btn.data().deactivate();
+			}
+			a.find('.tools').remove();
+			a.find('.wb-settings').remove();
+			readOnly = ro;
+			var sc = a.find('.scroll-container');
+			if (readOnly) {
+				t = $('#wb-tools-readonly').clone().attr('id', '');
+				a.append(t);
+				sc.off('scroll', scrollHandler);
+			} else {
+				t = $('#wb-tools').clone().attr('id', '');
+				s = $("#wb-settings").clone().attr('id', '');
+				a.append(t).append(s);
+				sc.on('scroll', scrollHandler);
+			}
+			showCurentSlide();
+			t = a.find('.tools'), s = a.find(".wb-settings");
+			internalInit();
+		}
+	};
+	wb.init = function(_wbId, tid, ro) {
 		wb.id = _wbId;
 		a = $('#' + tid);
-		t = a.find('.tools'), s = a.find(".wb-settings");
+		wb.setReadOnly(ro);
 		addCanvas();
-		internalInit(t);
-		a.find('.scroll-container').on('scroll', function(e) {
-			$(this).find('.canvas-container').each(function(idx) {
-				var h = $(this).height(), pos = $(this).position();
-				if (slide != idx &&pos.top > BUMPER - h && pos.top < BUMPER) {
-					//TODO FIXME might be done without iterating
-					//console.log("Found:", idx);
-					slide = idx;
-					wbAction('setSlide', JSON.stringify({
-						wbId: wb.id
-						, slide: idx
-					}));
-					return false;
-				}
-			});
-		});
 	};
 	wb.resize = function(w, h) {
 		if (t.position().left + t.width() > a.width()) {
@@ -826,7 +888,11 @@ var Wb = function() {
 	};
 	wb.setSlide = function(_sl) {
 		slide = _sl;
-		a.find('.scroll-container .canvas-container')[slide].scrollIntoView();
+		if (readOnly) {
+			showCurentSlide();
+		} else {
+			a.find('.scroll-container .canvas-container')[slide].scrollIntoView();
+		}
 	};
 	wb.createObj = function(o) {
 		switch(o.type) {
@@ -882,7 +948,7 @@ var Wb = function() {
 	return wb;
 };
 var WbArea = (function() {
-	var container, area, tabs, scroll, self = {};
+	var container, area, tabs, scroll, readOnly = true, self = {};
 
 	function refreshTabs() {
 		tabs.tabs("refresh").find('ul').removeClass('ui-corner-all').removeClass('ui-widget-header');
@@ -961,31 +1027,61 @@ var WbArea = (function() {
 	self.getCanvas = function(id) {
 		return self.getWb(id).getCanvas();
 	};
+	self.setReadOnly = function(ro) {
+		readOnly = ro;
+		tabs.find(".ui-tabs-nav").sortable(readOnly ? "disable" : "enable");
+		var prev = tabs.find('.prev.om-icon'), next = tabs.find('.next.om-icon');
+		if (readOnly) {
+			if (prev.length > 0) {
+				prev.parent().remove();
+				next.parent().remove();
+			}
+			$(window).off('keyup', deleteHandler);
+		} else {
+			if (prev.length == 0) {
+				var cc = tabs.find('.wb-tabbar .scroll-container')
+					, left = $('#wb-tabbar-ctrls-left').clone().attr('id', '')
+					, right = $('#wb-tabbar-ctrls-right').clone().attr('id', '');
+				cc.before(left).after(right);
+				tabs.find('.add.om-icon').click(function() {
+					wbAction('createWb');
+				});
+				tabs.find('.prev.om-icon').click(function() {
+					scroll.scrollLeft(scroll.scrollLeft() - 30);
+				});
+				tabs.find('.next.om-icon').click(function() {
+					scroll.scrollLeft(scroll.scrollLeft() + 30);
+				});
+				$(window).keyup(deleteHandler);
+			}
+		}
+		tabs.find(".ui-tabs-panel").each(function(idx) {
+			$(this).data().setReadOnly(readOnly);
+		});
+	}
 	self.init = function() {
 		container = $(".room.wb.area");
 		tabs = container.find('.tabs').tabs({
-			activate: function(event, ui) {
+			beforeActivate: function(e, ui) {
+				var res = true;
+				if (e.originalEvent && e.originalEvent.type === 'click') {
+					res = !readOnly;
+				}
+				return res;
+			}
+			, activate: function(e, ui) {
 				wbAction('activeWb', JSON.stringify({id: ui.newTab.data('wb-id')}));
 			}
 		});
 		scroll = tabs.find('.scroll-container');
+		area = container.find(".wb-area");
 		tabs.find(".ui-tabs-nav").sortable({
 			axis: "x"
 			, stop: function() {
 				refreshTabs();
 			}
 		});
-		tabs.find('.add.om-icon').click(function() {
-			wbAction('createWb');
-		});
-		tabs.find('.prev.om-icon').click(function() {
-			scroll.scrollLeft(scroll.scrollLeft() - 30);
-		});
-		tabs.find('.next.om-icon').click(function() {
-			scroll.scrollLeft(scroll.scrollLeft() + 30);
-		});
-		area = container.find(".wb-area");
-		$(window).keyup(deleteHandler);
+		self.setReadOnly(readOnly);
 	};
 	self.destroy = function() {
 		$(window).off('keyup', deleteHandler);
@@ -995,9 +1091,12 @@ var WbArea = (function() {
 			, li = $('#wb-area-tab').clone().attr('id', '').data('wb-id', obj.id)
 			, wb = $('#wb-area').clone().attr('id', tid);
 		li.find('a').text(obj.name).attr('title', obj.name).attr('href', "#" + tid);
-		li.find('button').click(function() {
-			wbAction('removeWb', JSON.stringify({id: obj.id}));
-		});
+		if (!readOnly) {
+			li.append($('#wb-tab-close').clone().attr('id', ''));
+			li.find('button').click(function() {
+				wbAction('removeWb', JSON.stringify({id: obj.id}));
+			});
+		}
 	
 		tabs.find(".ui-tabs-nav").append(li);
 		tabs.append(wb);
@@ -1005,7 +1104,7 @@ var WbArea = (function() {
 	
 		var wbo = Wb();
 		wb.data(wbo);
-		wbo.init(obj.id, tid);
+		wbo.init(obj.id, tid, readOnly);
 		_resizeWbs();
 	}
 	self.add = function(obj) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/7859e815/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css b/openmeetings-web/src/main/webapp/css/room.css
index 3b6a9ea..96d9412 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -139,10 +139,18 @@
 	width: 38px;
 	height: 420px;
 }
+.room.wb.area .tools.readonly.vertical {
+	width: 38px;
+	height: 60px;
+}
 .room.wb.area .tools.horisontal {
 	width: 420px;
 	height: 38px;
 }
+.room.wb.area .tools.readonly.horisontal {
+	width: 60px;
+	height: 38px;
+}
 .room.wb.area .tools .om-icon.big {
 	float: left;
 	vertical-align: top;


[04/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] slide change is implemented

Posted by so...@apache.org.
[OPENMEETINGS-551] slide change is implemented


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/6b542f39
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/6b542f39
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/6b542f39

Branch: refs/heads/master
Commit: 6b542f39c72aad7cade469878d0a7e8dd50c3438
Parents: f5476aa
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sat Apr 1 11:19:21 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sat Apr 1 11:19:21 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/db/dto/room/Whiteboard.java    |  9 +++
 .../openmeetings/web/room/wb/WbPanel.java       | 13 ++--
 .../apache/openmeetings/web/room/wb/fabric.js   |  1 +
 .../org/apache/openmeetings/web/room/wb/wb.js   | 73 +++++++++++++-------
 4 files changed, 68 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/6b542f39/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
index 1b3acab..3f16125 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
@@ -40,6 +40,7 @@ public class Whiteboard {
 	private Boolean fullFit = true;
 	private Map<String, JSONObject> roomItems = new ConcurrentHashMap<>();
 	private Date created = new Date();
+	private int slide = 0;
 	private int zIndex = 1;
 	private String name;
 
@@ -130,4 +131,12 @@ public class Whiteboard {
 	public void setName(String name) {
 		this.name = name;
 	}
+
+	public int getSlide() {
+		return slide;
+	}
+
+	public void setSlide(int slide) {
+		this.slide = slide;
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/6b542f39/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index a292000..2375130 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -83,6 +83,7 @@ public class WbPanel extends Panel {
 		createWb
 		, removeWb
 		, activeWb
+		, setSlide
 		, createObj
 		, modifyObj
 		, deleteObj
@@ -135,6 +136,13 @@ public class WbPanel extends Panel {
 							}
 						}
 							break;
+						case setSlide:
+						{
+							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
+							wb.setSlide(obj.optInt("slide", 0));
+							sendWbOthers(String.format("WbArea.%s", a.name()), obj);
+						}
+							break;
 						case createObj:
 						{
 							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
@@ -362,11 +370,8 @@ public class WbPanel extends Panel {
 					.put("top", UPLOAD_WB_TOP)
 					.put("width", fi.getWidth() == null ? DEFAULT_WIDTH : fi.getWidth())
 					.put("height", fi.getHeight() == null ? DEFAULT_HEIGHT : fi.getHeight())
-					//,"angle":32.86
-					//,"crossOrigin":""
 					.put("uid", wuid)
-					//,"filters":[]
-					//,"resizeFilters":[]
+					.put("slide", wb.getSlide())
 					;
 			wb.put(wuid, file);
 			final String ruid = wbs.getUid();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/6b542f39/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
index a07bc79..f875a24 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.js
@@ -1,5 +1,6 @@
 /* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */
  /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
+/* version 1.7.8 */
 /* Licensed MIT https://github.com/kangax/fabric.js/blob/master/LICENSE */
 var fabric = fabric || { version: "1.7.8" };
 if (typeof exports !== 'undefined') {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/6b542f39/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index 4952f58..57f6943 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -482,7 +482,9 @@ var Clipart = function(wb, btn) {
 }
 var Wb = function() {
 	const ACTIVE = 'active';
-	var wb = {id: -1}, a, t, s, canvases = [], mode, slide = 0, resizable = true;
+	const BUMPER = 100;
+	var wb = {id: -1}, a, t, s, canvases = [], mode, slide = 0, width = 0, height = 0
+			, minWidth = 0, minHeight = 0;
 
 	function getBtn(m) {
 		return t.find(".om-icon." + (m || mode));
@@ -664,22 +666,18 @@ var Wb = function() {
 				break;
 			case 'Presentation':
 			{
-				if (resizable && !_o.deleted) {
-					resizable = false;
-				}
+				minWidth = Math.max(minWidth, _o.width);
+				minHeight = Math.max(minHeight, _o.height);
+				width = Math.max(minWidth, width);
+				height = Math.max(minHeight, height);
 				var count = _o.deleted ? 1 : _o.count;
 				for (var i = 0; i < count; ++i) {
 					if (canvases.length < i + 1) {
 						addCanvas();
 					}
 					var canvas = canvases[i];
-					/*
-					 * TODO block resizing
-					*/
-					canvas.setBackgroundImage(_o._src + "&slide=" + i, canvas.renderAll.bind(canvas), {
-						/*backgroundImageOpacity: 0.5
-						, */backgroundImageStretch: false
-					}).setWidth(Math.max(canvas.width, _o.width)).setHeight(Math.max(canvas.height, _o.height));
+					canvas.setBackgroundImage(_o._src + "&slide=" + i, canvas.renderAll.bind(canvas), {})
+							.setWidth(width).setHeight(height);
 				}
 			}
 				break;
@@ -792,6 +790,21 @@ var Wb = function() {
 		t = a.find('.tools'), s = a.find(".wb-settings");
 		addCanvas();
 		internalInit(t);
+		a.find('.scroll-container').on('scroll', function(e) {
+			$(this).find('.canvas-container').each(function(idx) {
+				var h = $(this).height(), pos = $(this).position();
+				if (slide != idx &&pos.top > BUMPER - h && pos.top < BUMPER) {
+					//TODO FIXME might be done without iterating
+					//console.log("Found:", idx);
+					slide = idx;
+					wbAction('setSlide', JSON.stringify({
+						wbId: wb.id
+						, slide: idx
+					}));
+					return false;
+				}
+			});
+		});
 	};
 	wb.resize = function(w, h) {
 		if (t.position().left + t.width() > a.width()) {
@@ -802,16 +815,19 @@ var Wb = function() {
 				, collision: "fit"
 			});
 		}
-		if (resizable) {
-			//TODO FIXME need to be checked
-			wb.eachCanvas(function(canvas) {
-				canvas.setWidth(w).setHeight(h);
-			});
-		}
+		width = Math.max(minWidth, w);
+		height = Math.max(minHeight, h);
+		wb.eachCanvas(function(canvas) {
+			canvas.setWidth(width).setHeight(height);
+		});
 	};
 	wb.load = function(arr) {
 		_createObject(arr, _createHandler);
 	};
+	wb.setSlide = function(_sl) {
+		slide = _sl;
+		a.find('.scroll-container .canvas-container')[slide].scrollIntoView();
+	};
 	wb.createObj = function(o) {
 		switch(o.type) {
 			case 'pointer':
@@ -925,6 +941,17 @@ var WbArea = (function() {
 			}
 		});
 	}
+	function _resizeWbs() {
+		var w = area.width(), hh = area.height();
+		var wbTabs = area.find(".tabs.ui-tabs");
+		var tabPanels = wbTabs.find(".ui-tabs-panel");
+		var wbah = hh - 5 - wbTabs.find("ul.ui-tabs-nav").height();
+		tabPanels.height(wbah);
+		tabPanels.each(function(idx) {
+			$(this).data().resize(w - 25, wbah - 20);
+		});
+		wbTabs.find(".ui-tabs-panel .scroll-container").height(wbah);
+	}
 	self.getWbTabId = function(id) {
 		return "wb-tab-" + id;
 	};
@@ -979,6 +1006,7 @@ var WbArea = (function() {
 		var wbo = Wb();
 		wb.data(wbo);
 		wbo.init(obj.id, tid);
+		_resizeWbs();
 	}
 	self.add = function(obj) {
 		self.create(obj);
@@ -990,6 +1018,9 @@ var WbArea = (function() {
 	self.load = function(json) {
 		self.getWb(json.wbId).load(json.obj);
 	};
+	self.setSlide = function(json) {
+		self.getWb(json.wbId).setSlide(json.slide);
+	};
 	self.createObj = function(json) {
 		self.getWb(json.wbId).createObj(json.obj);
 	};
@@ -1013,13 +1044,7 @@ var WbArea = (function() {
 
 		var wbTabs = area.find(".tabs.ui-tabs");
 		wbTabs.height(hh);
-		var tabPanels = wbTabs.find(".ui-tabs-panel");
-		var wbah = hh - 5 - wbTabs.find("ul.ui-tabs-nav").height();
-		tabPanels.height(wbah);
-		tabPanels.each(function(idx) {
-			$(this).data('resize')(w - 20, wbah);
-		});
-		wbTabs.find(".ui-tabs-panel .scroll-container").height(wbah);
+		_resizeWbs();
 	}
 	return self;
 })();


[13/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] basic save is added, code clean-up

Posted by so...@apache.org.
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5394af08/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.min.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.min.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.min.js
index b860a2b..72b6cad 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.min.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/fabric.min.js
@@ -1,10 +1,10 @@
 /* Licensed MIT */
-var fabric=fabric||{version:"1.7.8"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require("jsdom").jsdom(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E")),fabric.document.createWindow?fabric.window=fabric.document.createWindow():fabric.window=fabric.document.parentWindow),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.iMatrix=[1,0,0,1,0,0],fabric.charWidthsCache={}
 ,fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function e(t,e){if(this.__eventListeners||(this.__eventListeners={}),1===arguments.length)for(var i in t)this.on(i,t[i]);else this.__eventListeners[t]||(this.__eventListeners[t]=[]),this.__eventListeners[t].push(e);return this}function i(e,i){if(this.__eventListeners){if(0===arguments.length)for(e in this.__eventListeners)t.call(this,e);else if(1===arguments.length&&"object"==typeof arguments[0])for(var r in e)t.call(this,r,e[r]);else t.call(this,e,i);return this}}function r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r<n;r++)i[r]&&i[r].call(this,e||{});return this.__eventListeners[t]=i.filter(function(t){return t!==!1}),this}}}fabric.Observable={observe:e,stopObserving:i
 ,fire:r,on:e,off:i,trigger:r}}(),fabric.Collection={_objects:[],add:function(){if(this._objects.push.apply(this._objects,arguments),this._onObjectAdded)for(var t=0,e=arguments.length;t<e;t++)this._onObjectAdded(arguments[t]);return this.renderOnAddRemove&&this.renderAll(),this},insertAt:function(t,e,i){var r=this.getObjects();return i?r[e]=t:r.splice(e,0,t),this._onObjectAdded&&this._onObjectAdded(t),this.renderOnAddRemove&&this.renderAll(),this},remove:function(){for(var t,e=this.getObjects(),i=!1,r=0,n=arguments.length;r<n;r++)t=e.indexOf(arguments[r]),t!==-1&&(i=!0,e.splice(t,1),this._onObjectRemoved&&this._onObjectRemoved(arguments[r]));return this.renderOnAddRemove&&i&&this.renderAll(),this},forEachObject:function(t,e){for(var i=this.getObjects(),r=0,n=i.length;r<n;r++)t.call(e,i[r],r,i);return this},getObjects:function(t){return"undefined"==typeof t?this._objects:this._objects.filter(function(e){return e.type===t})},item:function(t){return this.getObjects()[t]},isEmpty:functio
 n(){return 0===this.getObjects().length},size:function(){return this.getObjects().length},contains:function(t){return this.getObjects().indexOf(t)>-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},fabric.CommonMethods={_setOptions:function(t){for(var e in t)this.set(e,t[e])},_initGradient:function(t,e){!t||!t.colorStops||t instanceof fabric.Gradient||this.set(e,new fabric.Gradient(t))},_initPattern:function(t,e,i){!t||!t.source||t instanceof fabric.Pattern?i&&i():this.set(e,new fabric.Pattern(t,i))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var e=fabric.util.getFunctionBody(t.clipTo);"undefined"!=typeof e&&(this.clipTo=new Function("ctx",e))}},_setObject:function(t){for(var e in t)this._set(e,t[e])},set:function(t,e){return"object"==typeof t?this._setObject(t):"function"==typeof e&&"clipTo"!==t?this._set(t,e(this.get(t))):this._set(t,e),this},_set:function(t,e){this[t]=e},toggle:function(t){v
 ar e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},get:function(t){return this[t]}},function(t){var e=Math.sqrt,i=Math.atan2,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return i!==-1&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e),n=t.x*r-t.y*i,s=t.x*i+t.y*r;return{x:n,y:s}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.Point(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])},makeBoundingBoxFromPoints:function(t){var e=[t[0].x,t[1].x,t[2].x,t[3].x],i=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fab
 ric.util.array.min(s),a=fabric.util.array.max(s),h=Math.abs(o-a);return{left:i,top:o,width:n,height:h}},invertTransform:function(t){var e=1/(t[0]*t[3]-t[1]*t[2]),i=[e*t[3],-e*t[1],-e*t[2],e*t[0]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},resolveNamespace:function(e){if(!e)return fabric;var i,r=e.split("."),n=r.length,s=t||fabric.window;for(i=0;i<n;++i)s=s[r[i]];return s},loadImage:function(t,e,i,r){if
 (!t)return void(e&&e.call(i,t));var n=fabric.util.createImage();n.onload=function(){e&&e.call(i,n),n=n.onload=n.onerror=null},n.onerror=function(){fabric.log("Error loading "+n.src),e&&e.call(i,null,!0),n=n.onload=n.onerror=null},0!==t.indexOf("data")&&r&&(n.crossOrigin=r),n.src=t},enlivenObjects:function(t,e,i,r){function n(){++o===a&&e&&e(s)}t=t||[];var s=[],o=0,a=t.length,h=!0;return a?void t.forEach(function(t,e){if(!t||!t.type)return void n();var o=fabric.util.getKlass(t.type,i);o.fromObject(t,function(i,o){o||(s[e]=i),r&&r(t,i,o),n()},h)}):void(e&&e(s))},enlivenPatterns:function(t,e){function i(){++n===s&&e&&e(r)}t=t||[];var r=[],n=0,s=t.length;return s?void t.forEach(function(t,e){t&&t.source?new fabric.Pattern(t,function(t){r[e]=t,i()}):(r[e]=t,i())}):void(e&&e(r))},groupSVGElements:function(t,e,i){var r;return r=new fabric.PathGroup(t,e),"undefined"!=typeof i&&r.setSourcePath(i),r},populateWithProperties:function(t,e,i){if(i&&"[object Array]"===Object.prototype.toString.cal
 l(i))for(var r=0,n=i.length;r<n;r++)i[r]in t&&(e[i[r]]=t[i[r]])},drawDashedLine:function(t,r,n,s,o,a){var h=s-r,c=o-n,l=e(h*h+c*c),u=i(c,h),f=a.length,d=0,g=!0;for(t.save(),t.translate(r,n),t.moveTo(0,0),t.rotate(u),r=0;l>r;)r+=a[d++%f],r>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(t){return t||(t=fabric.document.createElement("canvas")),t.getContext||"undefined"==typeof G_vmlCanvasManager||G_vmlCanvasManager.initElement(t),t},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(t){var e,i,r,n,s,o=t.prototype;for(e=o.stateProperties.length;e--;)i=o.stateProperties[e],r=i.charAt(0).toUpperCase()+i.slice(1),n="set"+r,s="get"+r,o[s]||(o[s]=function(t){return new Function('return this.get("'+t+'")')}(i)),o[n]||(o[n]=function(t){return new Function("value",'return this.set("'+t+'", value)')}(i))},clipContext:function(t,e){e.save(),e.beginPath(),t.clipTo(e),e.cl
 ip()},multiplyTransformMatrices:function(t,e,i){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],i?0:t[0]*e[4]+t[2]*e[5]+t[4],i?0:t[1]*e[4]+t[3]*e[5]+t[5]]},qrDecompose:function(t){var n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.setAngle(0)},getFunctionBody:function(t){return(String(t).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(t,e,i,r){r>0&&(e>r?e-=r:e=0,i>r?i-=r:i=0);var n,s,o=!0,a=t.getImageData(e,i,2*r||1,2*r||1),h=a.data.length;for(n=3;n<h&&(s=a.data[n],o=s<=0,o!==!1);n+=4);return a=null,o},parsePreserveAspectRatioAttribute:function(t){var e,i
 ="meet",r="Mid",n="Mid",s=t.split(" ");return s&&s.length&&(i=s.pop(),"meet"!==i&&"slice"!==i?(e=i,i="meet"):s.length&&(e=s.pop())),r="none"!==e?e.slice(1,4):"none",n="none"!==e?e.slice(5,8):"none",{meetOrSlice:i,alignX:r,alignY:n}},clearFabricFontCache:function(t){t?fabric.charWidthsCache[t]&&delete fabric.charWidthsCache[t]:fabric.charWidthsCache={}}}}("undefined"!=typeof exports?exports:this),function(){function t(t,r,s,o,h,c,l){var u=a.call(arguments);if(n[u])return n[u];var f=Math.PI,d=l*f/180,g=Math.sin(d),p=Math.cos(d),v=0,b=0;s=Math.abs(s),o=Math.abs(o);var m=-p*t*.5-g*r*.5,y=-p*r*.5+g*t*.5,_=s*s,x=o*o,C=y*y,S=m*m,w=_*x-_*C-x*S,O=0;if(w<0){var T=Math.sqrt(1-w/(_*x));s*=T,o*=T}else O=(h===c?-1:1)*Math.sqrt(w/(_*C+x*S));var j=O*s*y/o,k=-O*o*m/s,M=p*j-g*k+.5*t,P=g*j+p*k+.5*r,A=i(1,0,(m-j)/s,(y-k)/o),D=i((m-j)/s,(y-k)/o,(-m-j)/s,(-y-k)/o);0===c&&D>0?D-=2*f:1===c&&D<0&&(D+=2*f);for(var E=Math.ceil(Math.abs(D/f*2)),I=[],L=D/E,F=8/3*Math.sin(L/4)*Math.sin(L/4)/Math.sin(L/2),B=A+L,R
 =0;R<E;R++)I[R]=e(A,B,p,g,s,o,M,P,F,v,b),v=I[R][4],b=I[R][5],A=B,B+=L;return n[u]=I,I}function e(t,e,i,r,n,o,h,c,l,u,f){var d=a.call(arguments);if(s[d])return s[d];var g=Math.cos(t),p=Math.sin(t),v=Math.cos(e),b=Math.sin(e),m=i*n*v-r*o*b+h,y=r*n*v+i*o*b+c,_=u+l*(-i*n*p-r*o*g),x=f+l*(-r*n*p+i*o*g),C=m+l*(i*n*b+r*o*v),S=y+l*(r*n*b-i*o*v);return s[d]=[_,x,C,S,m,y],s[d]}function i(t,e,i,r){var n=Math.atan2(e,t),s=Math.atan2(r,i);return s>=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,b,m,y=Math.sqrt,_=Math.min,x=Math.max,C=Math.abs,S=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var O=0;O<2;++O)if(O>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),C(u)<1e-12){if(C(f)<1e-12)continue;g=-d/f,0<g&&g<1&&S.push(g)}else b=f*f-4*d*u,b<0||(m=y(b),p=(-f+m)/(2*u),0<p&&p<1&&S.push(p),v=(-f-m)/(2*u),0<v&&v<1&&S.push(v));for(var T,j,k,M=S.length,P=M;M--;)g=S[M],k=1-g,T=k*k*k*t+3*k*k*g*i+3*k*g*g*n+g*g*g*h,w[0][M]=T,j=k*k*k*
 e+3*k*k*g*r+3*k*g*g*s+g*g*g*c,w[1][M]=j;w[0][P]=t,w[1][P]=e,w[0][P+1]=h,w[1][P+1]=c;var A=[{x:_.apply(null,w[0]),y:_.apply(null,w[1])},{x:x.apply(null,w[0]),y:x.apply(null,w[1])}];return o[l]=A,A}var n={},s={},o={},a=Array.prototype.join;fabric.util.drawArc=function(e,i,r,n){for(var s=n[0],o=n[1],a=n[2],h=n[3],c=n[4],l=n[5],u=n[6],f=[[],[],[],[]],d=t(l-i,u-r,s,o,h,c,a),g=0,p=d.length;g<p;g++)f[g][0]=d[g][0]+i,f[g][1]=d[g][1]+r,f[g][2]=d[g][2]+i,f[g][3]=d[g][3]+r,f[g][4]=d[g][4]+i,f[g][5]=d[g][5]+r,e.bezierCurveTo.apply(e,f[g])},fabric.util.getBoundsOfArc=function(e,i,n,s,o,a,h,c,l){for(var u,f=0,d=0,g=[],p=t(c-e,l-i,n,s,a,h,o),v=0,b=p.length;v<b;v++)u=r(f,d,p[v][0],p[v][1],p[v][2],p[v][3],p[v][4],p[v][5]),g.push({x:u[0].x+e,y:u[0].y+i}),g.push({x:u[1].x+e,y:u[1].y+i}),f=p[v][4],d=p[v][5];return g},fabric.util.getBoundsOfCurve=r}(),function(){function t(t,e){for(var i=s.call(arguments,2),r=[],n=0,o=t.length;n<o;n++)r[n]=i.length?t[n][e].apply(t[n],i):t[n][e].call(t[n]);return r}funct
 ion e(t,e){return n(t,e,function(t,e){return t>=e})}function i(t,e){return n(t,e,function(t,e){return t<e})}function r(t,e){for(var i=t.length;i--;)t[i]=e;return t}function n(t,e,i){if(t&&0!==t.length){var r=t.length-1,n=e?t[r][e]:t[r];if(e)for(;r--;)i(t[r][e],n)&&(n=t[r][e]);else for(;r--;)i(t[r],n)&&(n=t[r]);return n}}var s=Array.prototype.slice;Array.prototype.indexOf||(Array.prototype.indexOf=function(t){if(void 0===this||null===this)throw new TypeError;var e=Object(this),i=e.length>>>0;if(0===i)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:0!==r&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=i)return-1;for(var n=r>=0?r:Math.max(i-Math.abs(r),0);n<i;n++)if(n in e&&e[n]===t)return n;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){for(var i=0,r=this.length>>>0;i<r;i++)i in this&&t.call(e,this[i],i,this)}),Array.prototype.map||(Array.prototype.map=function(t,e){for(var i=[
 ],r=0,n=this.length>>>0;r<n;r++)r in this&&(i[r]=t.call(e,this[r],r,this));return i}),Array.prototype.every||(Array.prototype.every=function(t,e){for(var i=0,r=this.length>>>0;i<r;i++)if(i in this&&!t.call(e,this[i],i,this))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t,e){for(var i=0,r=this.length>>>0;i<r;i++)if(i in this&&t.call(e,this[i],i,this))return!0;return!1}),Array.prototype.filter||(Array.prototype.filter=function(t,e){for(var i,r=[],n=0,s=this.length>>>0;n<s;n++)n in this&&(i=this[n],t.call(e,i,n,this)&&r.push(i));return r}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var e,i=this.length>>>0,r=0;if(arguments.length>1)e=arguments[1];else for(;;){if(r in this){e=this[r++];break}if(++r>=i)throw new TypeError}for(;r<i;r++)r in this&&(e=t.call(null,e,this[r],r,this));return e}),fabric.util.array={fill:r,invoke:t,min:i,max:e}}(),function(){function t(e,i,r){if(r)if(!fabric.isLikelyNode&&i instanceof Element)e=i;else if(i instanceof Ar
 ray){e=[];for(var n=0,s=i.length;n<s;n++)e[n]=t({},i[n],r)}else if(i&&"object"==typeof i)for(var o in i)i.hasOwnProperty(o)&&(e[o]=t({},i[o],r));else e=i;else for(var o in i)e[o]=i[o];return e}function e(e,i){return t({},e,i)}fabric.util.object={extend:t,clone:e}}(),function(){function t(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})}function e(t,e){return t.charAt(0).toUpperCase()+(e?t.slice(1):t.slice(1).toLowerCase())}function i(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:t,capitalize:e,escapeXml:i}}(),function(){var t=Array.prototype.slice,e=Function.prototype.apply,i=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var n,s=this,o=t.call(arguments,1);return n=o.length?function(){return e.call(s,this ins
 tanceof i?this:r,o.concat(t.call(arguments)))}:function(){return e.call(s,this instanceof i?this:r,arguments)},i.prototype=this.prototype,n.prototype=new i,n})}(),function(){function t(){}function e(t){var e=this.constructor.superclass.prototype[t];return arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(this)}function i(){function i(){this.initialize.apply(this,arguments)}var s=null,a=r.call(arguments,0);"function"==typeof a[0]&&(s=a.shift()),i.superclass=s,i.subclasses=[],s&&(t.prototype=s.prototype,i.prototype=new t,s.subclasses.push(i));for(var h=0,c=a.length;h<c;h++)o(i,a[h],s);return i.prototype.initialize||(i.prototype.initialize=n),i.prototype.constructor=i,i.prototype.callSuper=e,i}var r=Array.prototype.slice,n=function(){},s=function(){for(var t in{toString:1})if("toString"===t)return!1;return!0}(),o=function(t,e,i){for(var r in e)r in t.prototype&&"function"==typeof t.prototype[r]&&(e[r]+"").indexOf("callSuper")>-1?t.prototype[r]=function(t){return function(){va
 r r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[r]=e[r],s&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=i}(),function(){function t(t){var e,i,r=Array.prototype.slice.call(arguments,1),n=r.length;for(i=0;i<n;i++)if(e=typeof t[r[i]],!/^(?:function|object|unknown)$/.test(e))return!1;return!0}function e(t,e){return{handler:e,wrappedHandler:i(t,e)}}function i(t,e){return function(i){e.call(o(t),i||fabric.window.event)}}function r(t,e){return function(i){if(p[t]&&p[t][e])for(var r=p[t][e],n=0,s=r.length;n<s;n++)r[n].call(this,i||fabric.window.event)}}function n(t){t||(t=fabric.window.event);var e=t.target||(typeof t.srcElement!==h?t.srcElement:null),i=fabric.util.getScrollLeftTop(e);return{x:v(t)+i.left,y:b(t)+i.top}}function s(t,e,i){var r="to
 uchend"===t.type?"changedTouches":"touches";return t[r]&&t[r][0]?t[r][0][e]-(t[r][0][e]-t[r][0][i])||t[i]:t[i]}var o,a,h="unknown",c=function(){var t=0;return function(e){return e.__uniqueID||(e.__uniqueID="uniqueID__"+t++)}}();!function(){var t={};o=function(e){return t[e]},a=function(e,i){t[e]=i}}();var l,u,f=t(fabric.document.documentElement,"addEventListener","removeEventListener")&&t(fabric.window,"addEventListener","removeEventListener"),d=t(fabric.document.documentElement,"attachEvent","detachEvent")&&t(fabric.window,"attachEvent","detachEvent"),g={},p={};f?(l=function(t,e,i,r){t.addEventListener(e,i,!d&&r)},u=function(t,e,i,r){t.removeEventListener(e,i,!d&&r)}):d?(l=function(t,i,r){var n=c(t);a(n,t),g[n]||(g[n]={}),g[n][i]||(g[n][i]=[]);var s=e(n,r);g[n][i].push(s),t.attachEvent("on"+i,s.wrappedHandler)},u=function(t,e,i){var r,n=c(t);if(g[n]&&g[n][e])for(var s=0,o=g[n][e].length;s<o;s++)r=g[n][e][s],r&&r.handler===i&&(t.detachEvent("on"+e,r.wrappedHandler),g[n][e][s]=null)}
 ):(l=function(t,e,i){var n=c(t);if(p[n]||(p[n]={}),!p[n][e]){p[n][e]=[];var s=t["on"+e];s&&p[n][e].push(s),t["on"+e]=r(n,e)}p[n][e].push(i)},u=function(t,e,i){var r=c(t);if(p[r]&&p[r][e])for(var n=p[r][e],s=0,o=n.length;s<o;s++)n[s]===i&&n.splice(s,1)}),fabric.util.addListener=l,fabric.util.removeListener=u;var v=function(t){return typeof t.clientX!==h?t.clientX:0},b=function(t){return typeof t.clientY!==h?t.clientY:0};fabric.isTouchSupported&&(v=function(t){return s(t,"pageX","clientX")},b=function(t){return s(t,"pageY","clientY")}),fabric.util.getPointer=n,fabric.util.object.extend(fabric.util,fabric.Observable)}(),function(){function t(t,e){var i=t.style;if(!i)return t;if("string"==typeof e)return t.style.cssText+=";"+e,e.indexOf("opacity")>-1?s(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)if("opacity"===r)s(t,e[r]);else{var n="float"===r||"cssFloat"===r?"undefined"==typeof i.styleFloat?"cssFloat":"styleFloat":r;i[n]=e[r]}return t}var e=fabric.document.createElement("
 div"),i="string"==typeof e.style.opacity,r="string"==typeof e.style.filter,n=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(t){return t};i?s=function(t,e){return t.style.opacity=e,t}:r&&(s=function(t,e){var i=t.style;return t.currentStyle&&!t.currentStyle.hasLayout&&(i.zoom=1),n.test(i.filter)?(e=e>=.9999?"":"alpha(opacity="+100*e+")",i.filter=i.filter.replace(n,e)):i.filter+=" alpha(opacity="+100*e+")",t}),fabric.util.setStyle=t}(),function(){function t(t){return"string"==typeof t?fabric.document.getElementById(t):t}function e(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function i(t,e){t&&(" "+t.className+" ").indexOf(" "+e+" ")===-1&&(t.className+=(t.className?" ":"")+e)}function r(t,i,r){return"string"==typeof i&&(i=e(i,r)),t.parentNode&&t.parentNode.replaceChild(i,t),i.appendChild(t),i}function n(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{sc
 rollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&(t=t.parentNode||t.host,t===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}function s(t){var e,i,r=t&&t.ownerDocument,s={left:0,top:0},o={left:0,top:0},a={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!r)return o;for(var h in a)o[a[h]]+=parseInt(c(t,h),10)||0;return e=r.documentElement,"undefined"!=typeof t.getBoundingClientRect&&(s=t.getBoundingClientRect()),i=n(t),{left:s.left+i.left-(e.clientLeft||0)+o.left,top:s.top+i.top-(e.clientTop||0)+o.top}}var o,a=Array.prototype.slice,h=function(t){return a.call(t,0)};try{o=h(fabric.document.childNodes)instanceof Array}catch(t){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var c;c=fabric.document.defaultView&&fabric.document.defaultView.getComputedSty
 le?function(t,e){var i=fabric.document.defaultView.getComputedStyle(t,null);return i?i[e]:void 0}:function(t,e){var i=t.style[e];return!i&&t.currentStyle&&(i=t.currentStyle[e]),i},function(){function t(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),r?t.style[r]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t}function e(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=null),r?t.style[r]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}var i=fabric.document.documentElement.style,r="userSelect"in i?"userSelect":"MozUserSelect"in i?"MozUserSelect":"WebkitUserSelect"in i?"WebkitUserSelect":"KhtmlUserSelect"in i?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=t,fabric.util.makeElementSelectable=e}(),function(){function t(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.re
 adyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}fabric.util.getScript=t}(),fabric.util.getById=t,fabric.util.toArray=h,fabric.util.makeElement=e,fabric.util.addClass=i,fabric.util.wrapElement=r,fabric.util.getScrollLeftTop=n,fabric.util.getElementOffset=s,fabric.util.getElementStyle=c}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=r(),h=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(h=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),a.open(s,i,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(h),a}var r=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){retur
 n new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{var i=t[e]();if(i)return t[e]}catch(t){}}();fabric.util.request=i}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){"undefined"!=typeof console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(t){e(function(i){t||(t={});var r,n=i||+new Date,s=t.duration||500,o=n+s,a=t.onChange||function(){},h=t.abort||function(){return!1},c=t.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},l="startValue"in t?t.startValue:0,u="endValue"in t?t.endValue:100,f=t.byValue||u-l;t.onStart&&t.onStart(),function i(u){r=u||+new Date;var d=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(d,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(i))}(n)})}function e(){return i.apply(f
 abric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){fabric.window.setTimeout(t,1e3/60)};fabric.util.animate=t,fabric.util.requestAnimFrame=e}(),function(){function t(t,e,i){var r="rgba("+parseInt(t[0]+i*(e[0]-t[0]),10)+","+parseInt(t[1]+i*(e[1]-t[1]),10)+","+parseInt(t[2]+i*(e[2]-t[2]),10);return r+=","+(t&&e?parseFloat(t[3]+i*(e[3]-t[3])):1),r+=")"}function e(e,i,r,n){var s=new fabric.Color(e).getSource(),o=new fabric.Color(i).getSource();n=n||{},fabric.util.animate(fabric.util.object.extend(n,{duration:r||500,startValue:s,endValue:o,byValue:o,easing:function(e,i,r,s){var o=n.colorEasing?n.colorEasing(e,s):1-Math.cos(e/s*(Math.PI/2));return t(i,r,o)}}))}fabric.util.animateColor=e}(),function(){function t(t,e,i,r){return t<Math.abs(e)?(t=e,r=i/4):r=0===e&&0===t?i/(2*Math.PI)*Math.asin(1):i/(2*Math.P
 I)*Math.asin(e/t),{a:t,c:e,p:i,s:r}}function e(t,e,i){return t.a*Math.pow(2,10*(e-=1))*Math.sin((e*i-t.s)*(2*Math.PI)/t.p)}function i(t,e,i,r){return i*((t=t/r-1)*t*t+1)+e}function r(t,e,i,r){return t/=r/2,t<1?i/2*t*t*t+e:i/2*((t-=2)*t*t+2)+e}function n(t,e,i,r){return i*(t/=r)*t*t*t+e}function s(t,e,i,r){return-i*((t=t/r-1)*t*t*t-1)+e}function o(t,e,i,r){return t/=r/2,t<1?i/2*t*t*t*t+e:-i/2*((t-=2)*t*t*t-2)+e}function a(t,e,i,r){return i*(t/=r)*t*t*t*t+e}function h(t,e,i,r){return i*((t=t/r-1)*t*t*t*t+1)+e}function c(t,e,i,r){return t/=r/2,t<1?i/2*t*t*t*t*t+e:i/2*((t-=2)*t*t*t*t+2)+e}function l(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e}function u(t,e,i,r){return i*Math.sin(t/r*(Math.PI/2))+e}function f(t,e,i,r){return-i/2*(Math.cos(Math.PI*t/r)-1)+e}function d(t,e,i,r){return 0===t?e:i*Math.pow(2,10*(t/r-1))+e}function g(t,e,i,r){return t===r?e+i:i*(-Math.pow(2,-10*t/r)+1)+e}function p(t,e,i,r){return 0===t?e:t===r?e+i:(t/=r/2,t<1?i/2*Math.pow(2,10*(t-1))+e:i/2*(-Math.pow(2,-
 10*--t)+2)+e)}function v(t,e,i,r){return-i*(Math.sqrt(1-(t/=r)*t)-1)+e}function b(t,e,i,r){return i*Math.sqrt(1-(t=t/r-1)*t)+e}function m(t,e,i,r){return t/=r/2,t<1?-i/2*(Math.sqrt(1-t*t)-1)+e:i/2*(Math.sqrt(1-(t-=2)*t)+1)+e}function y(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s,1===i)return r+n;a||(a=.3*s);var c=t(h,n,a,o);return-e(c,i,s)+r}function _(e,i,r,n){var s=1.70158,o=0,a=r;if(0===e)return i;if(e/=n,1===e)return i+r;o||(o=.3*n);var h=t(a,r,o,s);return h.a*Math.pow(2,-10*e)*Math.sin((e*n-h.s)*(2*Math.PI)/h.p)+h.c+i}function x(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s/2,2===i)return r+n;a||(a=s*(.3*1.5));var c=t(h,n,a,o);return i<1?-.5*e(c,i,s)+r:c.a*Math.pow(2,-10*(i-=1))*Math.sin((i*s-c.s)*(2*Math.PI)/c.p)*.5+c.c+r}function C(t,e,i,r,n){return void 0===n&&(n=1.70158),i*(t/=r)*t*((n+1)*t-n)+e}function S(t,e,i,r,n){return void 0===n&&(n=1.70158),i*((t=t/r-1)*t*((n+1)*t+n)+1)+e}function w(t,e,i,r,n){return void 0===n&&(n=1.70158),t/=r/2,t<1?i/2*(t*t
 *(((n*=1.525)+1)*t-n))+e:i/2*((t-=2)*t*(((n*=1.525)+1)*t+n)+2)+e}function O(t,e,i,r){return i-T(r-t,0,i,r)+e}function T(t,e,i,r){return(t/=r)<1/2.75?i*(7.5625*t*t)+e:t<2/2.75?i*(7.5625*(t-=1.5/2.75)*t+.75)+e:t<2.5/2.75?i*(7.5625*(t-=2.25/2.75)*t+.9375)+e:i*(7.5625*(t-=2.625/2.75)*t+.984375)+e}function j(t,e,i,r){return t<r/2?.5*O(2*t,0,i,r)+e:.5*T(2*t-r,0,i,r)+.5*i+e}fabric.util.ease={easeInQuad:function(t,e,i,r){return i*(t/=r)*t+e},easeOutQuad:function(t,e,i,r){return-i*(t/=r)*(t-2)+e},easeInOutQuad:function(t,e,i,r){return t/=r/2,t<1?i/2*t*t+e:-i/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,i,r){return i*(t/=r)*t*t+e},easeOutCubic:i,easeInOutCubic:r,easeInQuart:n,easeOutQuart:s,easeInOutQuart:o,easeInQuint:a,easeOutQuint:h,easeInOutQuint:c,easeInSine:l,easeOutSine:u,easeInOutSine:f,easeInExpo:d,easeOutExpo:g,easeInOutExpo:p,easeInCirc:v,easeOutCirc:b,easeInOutCirc:m,easeInElastic:y,easeOutElastic:_,easeInOutElastic:x,easeInBack:C,easeOutBack:S,easeInOutBack:w,easeInBounce:O,easeOu
 tBounce:T,easeInOutBounce:j}}(),function(t){"use strict";function e(t){return t in O?O[t]:t}function i(t,e,i,r){var n,s="[object Array]"===Object.prototype.toString.call(e);return"fill"!==t&&"stroke"!==t||"none"!==e?"strokeDashArray"===t?e="none"===e?null:e.replace(/,/g," ").split(/\s+/).map(function(t){return parseFloat(t)}):"transformMatrix"===t?e=i&&i.transformMatrix?_(i.transformMatrix,p.parseTransformAttribute(e)):p.parseTransformAttribute(e):"visible"===t?(e="none"!==e&&"hidden"!==e,i&&i.visible===!1&&(e=!1)):"opacity"===t?(e=parseFloat(e),i&&"undefined"!=typeof i.opacity&&(e*=i.opacity)):"originX"===t?e="start"===e?"left":"end"===e?"right":"center":n=s?e.map(y):y(e,r):e="",!s&&isNaN(n)?e:n}function r(t){for(var e in T)if("undefined"!=typeof t[T[e]]&&""!==t[e]){if("undefined"==typeof t[e]){if(!p.Object.prototype[e])continue;t[e]=p.Object.prototype[e]}if(0!==t[e].indexOf("url(")){var i=new p.Color(t[e]);t[e]=i.setAlpha(m(i.getAlpha()*t[T[e]],2)).toRgba()}}return t}function n(t,
 e){for(var i,r,n=[],s=0;s<e.length;s++)i=e[s],r=t.getElementsByTagName(i),n=n.concat(Array.prototype.slice.call(r));return n}function s(t,e){var i,r;t.replace(/;\s*$/,"").split(";").forEach(function(t){var n=t.split(":");i=n[0].trim().toLowerCase(),r=n[1].trim(),e[i]=r})}function o(t,e){var i,r;for(var n in t)"undefined"!=typeof t[n]&&(i=n.toLowerCase(),r=t[n],e[i]=r)}function a(t,e){var i={};for(var r in p.cssRules[e])if(h(t,r.split(" ")))for(var n in p.cssRules[e][r])i[n]=p.cssRules[e][r][n];return i}function h(t,e){var i,r=!0;return i=l(t,e.pop()),i&&e.length&&(r=c(t,e)),i&&r&&0===e.length}function c(t,e){for(var i,r=!0;t.parentNode&&1===t.parentNode.nodeType&&e.length;)r&&(i=e.pop()),t=t.parentNode,r=l(t,i);return 0===e.length}function l(t,e){var i,r=t.nodeName,n=t.getAttribute("class"),s=t.getAttribute("id");if(i=new RegExp("^"+r,"i"),e=e.replace(i,""),s&&e.length&&(i=new RegExp("#"+s+"(?![a-zA-Z\\-]+)","i"),e=e.replace(i,"")),n&&e.length){n=n.split(" ");for(var o=n.length;o--;
 )i=new RegExp("\\."+n[o]+"(?![a-zA-Z\\-]+)","i"),e=e.replace(i,"")}return 0===e.length}function u(t,e){var i;if(t.getElementById&&(i=t.getElementById(e)),i)return i;var r,n,s=t.getElementsByTagName("*");for(n=0;n<s.length;n++)if(r=s[n],e===r.getAttribute("id"))return r}function f(t){for(var e=n(t,["use","svg:use"]),i=0;e.length&&i<e.length;){var r,s,o,a,h,c=e[i],l=c.getAttribute("xlink:href").substr(1),f=c.getAttribute("x")||0,g=c.getAttribute("y")||0,p=u(t,l).cloneNode(!0),v=(p.getAttribute("transform")||"")+" translate("+f+", "+g+")",b=e.length;if(d(p),/^svg$/i.test(p.nodeName)){var m=p.ownerDocument.createElement("g");for(o=0,a=p.attributes,h=a.length;o<h;o++)s=a.item(o),m.setAttribute(s.nodeName,s.nodeValue);for(;p.firstChild;)m.appendChild(p.firstChild);p=m}for(o=0,a=c.attributes,h=a.length;o<h;o++)s=a.item(o),"x"!==s.nodeName&&"y"!==s.nodeName&&"xlink:href"!==s.nodeName&&("transform"===s.nodeName?v=s.nodeValue+" "+v:p.setAttribute(s.nodeName,s.nodeValue));p.setAttribute("trans
 form",v),p.setAttribute("instantiated_by_use","1"),p.removeAttribute("id"),r=c.parentNode,r.replaceChild(p,c),e.length===b&&i++}}function d(t){var e,i,r,n,s=t.getAttribute("viewBox"),o=1,a=1,h=0,c=0,l=t.getAttribute("width"),u=t.getAttribute("height"),f=t.getAttribute("x")||0,d=t.getAttribute("y")||0,g=t.getAttribute("preserveAspectRatio")||"",v=!s||!C.test(t.nodeName)||!(s=s.match(j)),b=!l||!u||"100%"===l||"100%"===u,m=v&&b,_={},x="";if(_.width=0,_.height=0,_.toBeParsed=m,m)return _;if(v)return _.width=y(l),_.height=y(u),_;if(h=-parseFloat(s[1]),c=-parseFloat(s[2]),e=parseFloat(s[3]),i=parseFloat(s[4]),b?(_.width=e,_.height=i):(_.width=y(l),_.height=y(u),o=_.width/e,a=_.height/i),g=p.util.parsePreserveAspectRatioAttribute(g),"none"!==g.alignX&&(a=o=o>a?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return _;if((f||d)&&(x=" translate("+y(f)+" "+y(d)+") "),r=x+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");t.firstChild;)n.appen
 dChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),
-_}function g(t,e){for(;t&&(t=t.parentNode);)if(t.nodeName&&e.test(t.nodeName.replace("svg:",""))&&!t.getAttribute("instantiated_by_use"))return!0;return!1}var p=t.fabric||(t.fabric={}),v=p.util.object.extend,b=p.util.object.clone,m=p.util.toFixed,y=p.util.parseUnit,_=p.util.multiplyTransformMatrices,x=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,C=/^(symbol|image|marker|pattern|view|svg)$/i,S=/^(?:pattern|defs|symbol|metadata|clipPath|mask)$/i,w=/^(symbol|g|a|svg)$/i,O={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecor
 ation","text-anchor":"originX",opacity:"opacity"},T={stroke:"strokeOpacity",fill:"fillOpacity"};p.cssRules={},p.gradientDefs={},p.parseTransformAttribute=function(){function t(t,e){var i=Math.cos(e[0]),r=Math.sin(e[0]),n=0,s=0;3===e.length&&(n=e[1],s=e[2]),t[0]=i,t[1]=r,t[2]=-r,t[3]=i,t[4]=n-(i*n-r*s),t[5]=s-(r*n+i*s)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e,i){t[i]=Math.tan(p.util.degreesToRadians(e[0]))}function r(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var n=[1,0,0,1,0,0],s=p.reNum,o="(?:\\s+,?\\s*|,\\s*)",a="(?:(skewX)\\s*\\(\\s*("+s+")\\s*\\))",h="(?:(skewY)\\s*\\(\\s*("+s+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+")"+o+"("+s+"))?\\s*\\))",l="(?:(scale)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",u="(?:(translate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",f="(?:(matrix)\\s*\\(\\s*("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")\\s*\\))",d="(?:"+f+"|"+u+"|"+l+"|"+c+"|"+a+"|"+h+")",g="(?:"+d+"(?:"+o+"*"+
 d+")*)",v="^\\s*(?:"+g+"?)\\s*$",b=new RegExp(v),m=new RegExp(d,"g");return function(s){var o=n.concat(),a=[];if(!s||s&&!b.test(s))return o;s.replace(m,function(s){var h=new RegExp(d).exec(s).filter(function(t){return!!t}),c=h[1],l=h.slice(2).map(parseFloat);switch(c){case"translate":r(o,l);break;case"rotate":l[0]=p.util.degreesToRadians(l[0]),t(o,l);break;case"scale":e(o,l);break;case"skewX":i(o,l,2);break;case"skewY":i(o,l,1);break;case"matrix":o=l}a.push(o.concat()),o=n.concat()});for(var h=a[0];a.length>1;)a.shift(),h=p.util.multiplyTransformMatrices(h,a[0]);return h}}();var j=new RegExp("^\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*$");p.parseSVGDocument=function(t,e,i){if(t){f(t);var r=p.Object.__uid++,n=d(t),s=p.util.toArray(t.getElementsByTagName("*"));if(n.svgUid=r,0===s.length&&p.isLikelyNode){s=t.selectNodes('//*[name(.)!="svg"]');for(var o=[],a=0,h=s.length;a<h;a++)o[a]=s[a];s=o}var c=s.filter(function(t){return d(t),x.te
 st(t.nodeName.replace("svg:",""))&&!g(t,S)});if(!c||c&&!c.length)return void(e&&e([],{}));p.gradientDefs[r]=p.getGradientDefs(t),p.cssRules[r]=p.getCSSRules(t),p.parseElements(c,function(t){e&&e(t,n)},b(n),i)}};var k=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+p.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+p.reNum+"))?\\s+(.*)");v(p,{parseFontDeclaration:function(t,e){var i=t.match(k);if(i){var r=i[1],n=i[3],s=i[4],o=i[5],a=i[6];r&&(e.fontStyle=r),n&&(e.fontWeight=isNaN(parseFloat(n))?n:parseFloat(n)),s&&(e.fontSize=y(s)),a&&(e.fontFamily=a),o&&(e.lineHeight="normal"===o?1:o)}},getGradientDefs:function(t){var e,i,r,s=["linearGradient","radialGradient","svg:linearGradient","svg:radialGradient"],o=n(t,s),a=0,h={},c={};for(a=o.length;a--;)e=o[a],r=e.getAttribute("xlink:href"),i=e.getAttribute("id"),r&&(c[i]=r.substr(1)),h[i]=e;for(i in c){var l=h[c[i]].cloneNode(!0);for(e=h[i];l.firstChild;)e.append
 Child(l.firstChild)}return h},parseAttributes:function(t,n,s){if(t){var o,h,c={};"undefined"==typeof s&&(s=t.getAttribute("svgUid")),t.parentNode&&w.test(t.parentNode.nodeName)&&(c=p.parseAttributes(t.parentNode,n,s)),h=c&&c.fontSize||t.getAttribute("font-size")||p.Text.DEFAULT_SVG_FONT_SIZE;var l=n.reduce(function(e,i){return o=t.getAttribute(i),o&&(e[i]=o),e},{});l=v(l,v(a(t,s),p.parseStyleAttribute(t)));var u,f,d={};for(var g in l)u=e(g),f=i(u,l[g],c,h),d[u]=f;d&&d.font&&p.parseFontDeclaration(d.font,d);var b=v(c,d);return w.test(t.nodeName)?b:r(b)}},parseElements:function(t,e,i,r){new p.ElementsParser(t,e,i,r).parse()},parseStyleAttribute:function(t){var e={},i=t.getAttribute("style");return i?("string"==typeof i?s(i,e):o(i,e),e):e},parsePointsAttribute:function(t){if(!t)return null;t=t.replace(/,/g," ").trim(),t=t.split(/\s+/);var e,i,r=[];for(e=0,i=t.length;e<i;e+=2)r.push({x:parseFloat(t[e]),y:parseFloat(t[e+1])});return r},getCSSRules:function(t){for(var e,i=t.getElementsByT
 agName("style"),r={},n=0,s=i.length;n<s;n++){var o=i[n].textContent||i[n].text;o=o.replace(/\/\*[\s\S]*?\*\//g,""),""!==o.trim()&&(e=o.match(/[^{]*\{[\s\S]*?\}/g),e=e.map(function(t){return t.trim()}),e.forEach(function(t){for(var e=t.match(/([\s\S]*?)\s*\{([^}]*)\}/),i={},n=e[2].trim(),s=n.replace(/;$/,"").split(/\s*;\s*/),o=0,a=s.length;o<a;o++){var h=s[o].split(/\s*:\s*/),c=h[0],l=h[1];i[c]=l}t=e[1],t.split(",").forEach(function(t){t=t.replace(/^svg/i,"").trim(),""!==t&&(r[t]?p.util.object.extend(r[t],i):r[t]=p.util.object.clone(i))})}))}return r},loadSVGFromURL:function(t,e,i){function r(t){var r=t.responseXML;r&&!r.documentElement&&p.window.ActiveXObject&&t.responseText&&(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(t.responseText.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i,""))),r&&r.documentElement||e&&e(null),p.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)}t=t.replace(/^\n\s*/,"").trim(),new p.util.request(t,{method:"get",onComplete:r})
 },loadSVGFromString:function(t,e,i){t=t.trim();var r;if("undefined"!=typeof DOMParser){var n=new DOMParser;n&&n.parseFromString&&(r=n.parseFromString(t,"text/xml"))}else p.window.ActiveXObject&&(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(t.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i,"")));p.parseSVGDocument(r.documentElement,function(t,i){e(t,i)},i)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;t<e;t++)this.elements[t].setAttribute("svgUid",this.svgUid),function(t,e){setTimeout(function(){t.createObject(t.elements[e],e)},0)}(this,t)},fabric.ElementsParser.prototype.createObject=function(t
 ,e){var i=fabric[fabric.util.string.capitalize(t.tagName.replace("svg:",""))];if(i&&i.fromElement)try{this._createObject(i,t,e)}catch(t){fabric.log(t)}else this.checkIfDone()},fabric.ElementsParser.prototype._createObject=function(t,e,i){if(t.async)t.fromElement(e,this.createCallback(i,e),this.options);else{var r=t.fromElement(e,this.options);this.resolveGradient(r,"fill"),this.resolveGradient(r,"stroke"),this.reviver&&this.reviver(e,r),this.instances[i]=r,this.checkIfDone()}},fabric.ElementsParser.prototype.createCallback=function(t,e){var i=this;return function(r){i.resolveGradient(r,"fill"),i.resolveGradient(r,"stroke"),i.reviver&&i.reviver(e,r),i.instances[t]=r,i.checkIfDone()}},fabric.ElementsParser.prototype.resolveGradient=function(t,e){var i=t.get(e);if(/^url\(/.test(i)){var r=i.slice(5,i.length-1);fabric.gradientDefs[this.svgUid][r]&&t.set(e,fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][r],t))}},fabric.ElementsParser.prototype.checkIfDone=function(){0===--thi
 s.numElements&&(this.instances=this.instances.filter(function(t){return null!=t}),this.callback(this.instances))},function(t){"use strict";function e(t,e){this.x=t,this.y=e}var i=t.fabric||(t.fabric={});return i.Point?void i.warn("fabric.Point is already defined"):(i.Point=e,void(e.prototype={type:"point",constructor:e,add:function(t){return new e(this.x+t.x,this.y+t.y)},addEquals:function(t){return this.x+=t.x,this.y+=t.y,this},scalarAdd:function(t){return new e(this.x+t,this.y+t)},scalarAddEquals:function(t){return this.x+=t,this.y+=t,this},subtract:function(t){return new e(this.x-t.x,this.y-t.y)},subtractEquals:function(t){return this.x-=t.x,this.y-=t.y,this},scalarSubtract:function(t){return new e(this.x-t,this.y-t)},scalarSubtractEquals:function(t){return this.x-=t,this.y-=t,this},multiply:function(t){return new e(this.x*t,this.y*t)},multiplyEquals:function(t){return this.x*=t,this.y*=t,this},divide:function(t){return new e(this.x/t,this.y/t)},divideEquals:function(t){return th
 is.x/=t,this.y/=t,this},eq:function(t){return this.x===t.x&&this.y===t.y},lt:function(t){return this.x<t.x&&this.y<t.y},lte:function(t){return this.x<=t.x&&this.y<=t.y},gt:function(t){return this.x>t.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return"undefined"==typeof i&&(i=.5),i=Math.max(Math.min(1,i),0),new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(
 ){return new e(this.x,this.y)}}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});return i.Intersection?void i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},i.Intersection.intersectLineLine=function(t,r,n,s){var o,a=(s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x),h=(r.x-t.x)*(t.y-n.y)-(r.y-t.y)*(t.x-n.x),c=(s.y-n.y)*(r.x-t.x)-(s.x-n.x)*(r.y-t.y);if(0!==c){var l=a/c,u=h/c;0<=l&&l<=1&&0<=u&&u<=1?(o=new e("Intersection"),o.appendPoint(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y)))):o=new e}else o=new e(0===a||0===h?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){for(var n,s,o,a=new e,h=r.length,c=0;c<h;c++)n=r[c],s=r[(c+1)%h],o=e.intersectLineLine(t,i,n,s),a.appendPoints(o.points
 );return a.points.length>0&&(a.status="Intersection"),a},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;s<n;s++){var o=t[s],a=t[(s+1)%n],h=e.intersectLinePolygon(o,a,i);r.appendPoints(h.points)}return r.points.length>0&&(r.status="Intersection"),r},void(i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;return d.appendPoints(c.points),d.appendPoints(l.points),d.appendPoints(u.points),d.appendPoints(f.points),d.points.length>0&&(d.status="Intersection"),d}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}var r=t.fabric||(t.fabric={});return r.Color?void
  r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);if(o=(a+h)/2,a===h)n=s=0;else{var c=a-h;switch(s=o>.5?c/(2-a-h):c/(a+h),a){case t:n=(e-i)/c+(e<i?6:0);break;case e:n=(i-t)/c+2;break;case i:n=(t-e)/c+4}n/=6}return[Math.round(360*n),Math.round(100*s),Math.round(100*o)]},getSource:function(){return this._source},setSource:function(t){this._source=t},toRgb:function(){var t=this.getSource();return"rgb("+t[0]+","+t[1]+","+t[2]+")"},toRgba:function(){var t=this.getSource();return"rgba("+t[0]+","+t[1]+","+t[2]+","+t[3]+")"},toHsl:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return"hsl("+e[0]+","+e[1]+"%,
 "+e[2]+"%)"},toHsla:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return"hsla("+e[0]+","+e[1]+"%,"+e[2]+"%,"+t[3]+")"},toHex:function(){var t,e,i,r=this.getSource();return t=r[0].toString(16),t=1===t.length?"0"+t:t,e=r[1].toString(16),e=1===e.length?"0"+e:e,i=r[2].toString(16),i=1===i.length?"0"+i:i,t.toUpperCase()+e.toUpperCase()+i.toUpperCase()},toHexa:function(){var t,e=this.getSource();return t=255*e[3],t=t.toString(16),t=1===t.length?"0"+t:t,this.toHex()+t.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(t){var e=this.getSource();return e[3]=t,this.setSource(e),this},toGrayscale:function(){var t=this.getSource(),e=parseInt((.3*t[0]+.59*t[1]+.11*t[2]).toFixed(0),10),i=t[3];return this.setSource([e,e,e,i]),this},toBlackWhite:function(t){var e=this.getSource(),i=(.3*e[0]+.59*e[1]+.11*e[2]).toFixed(0),r=e[3];return t=t||127,i=Number(i)<Number(t)?0:255,this.setSource([i,i,i,r]),this},overlayWith:function(t){t instanceof e||(t=new 
 e(t));for(var i=[],r=this.getAlpha(),n=.5,s=this.getSource(),o=t.getSource(),a=0;a<3;a++)i.push(Math.round(s[a]*(1-n)+o[a]*n));return i[3]=r,this.setSource(i),this}},r.Color.reRGBa=/^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/,r.Color.reHSLa=/^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/,r.Color.reHex=/^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i,r.Color.colorNameMap={aqua:"#00FFFF",black:"#000000",blue:"#0000FF",fuchsia:"#FF00FF",gray:"#808080",grey:"#808080",green:"#008000",lime:"#00FF00",maroon:"#800000",navy:"#000080",olive:"#808000",orange:"#FFA500",purple:"#800080",red:"#FF0000",silver:"#C0C0C0",teal:"#008080",white:"#FFFFFF",yellow:"#FFFF00"},r.Color.fromRgb=function(t){return e.fromSource(e.sourceFromRgb(t))},r.Color.sourceFromRgb=function(t){var i=t.match(e.reRGBa);if(i){var r=parseInt(i[1],10)/(/%$/.test(i[1])?100:1)*(/%$/.test(i[1]
 )?255:1),n=parseInt(i[2],10)/(/%$/.test(i[2])?100:1)*(/%$/.test(i[2])?255:1),s=parseInt(i[3],10)/(/%$/.test(i[3])?100:1)*(/%$/.test(i[3])?255:1);return[parseInt(r,10),parseInt(n,10),parseInt(s,10),i[4]?parseFloat(i[4]):1]}},r.Color.fromRgba=e.fromRgb,r.Color.fromHsl=function(t){return e.fromSource(e.sourceFromHsl(t))},r.Color.sourceFromHsl=function(t){var r=t.match(e.reHSLa);if(r){var n,s,o,a=(parseFloat(r[1])%360+360)%360/360,h=parseFloat(r[2])/(/%$/.test(r[2])?100:1),c=parseFloat(r[3])/(/%$/.test(r[3])?100:1);if(0===h)n=s=o=c;else{var l=c<=.5?c*(h+1):c+h-c*h,u=2*c-l;n=i(u,l,a+1/3),s=i(u,l,a),o=i(u,l,a-1/3)}return[Math.round(255*n),Math.round(255*s),Math.round(255*o),r[4]?parseFloat(r[4]):1]}},r.Color.fromHsla=e.fromHsl,r.Color.fromHex=function(t){return e.fromSource(e.sourceFromHex(t))},r.Color.sourceFromHex=function(t){if(t.match(e.reHex)){var i=t.slice(t.indexOf("#")+1),r=3===i.length||4===i.length,n=8===i.length||4===i.length,s=r?i.charAt(0)+i.charAt(0):i.substring(0,2),o=r?i.c
 harAt(1)+i.charAt(1):i.substring(2,4),a=r?i.charAt(2)+i.charAt(2):i.substring(4,6),h=n?r?i.charAt(3)+i.charAt(3):i.substring(6,8):"FF";return[parseInt(s,16),parseInt(o,16),parseInt(a,16),parseFloat((parseInt(h,16)/255).toFixed(2))]}},void(r.Color.fromSource=function(t){var i=new e;return i.setSource(t),i}))}("undefined"!=typeof exports?exports:this),function(){function t(t){var e,i,r,n=t.getAttribute("style"),s=t.getAttribute("offset")||0;if(s=parseFloat(s)/(/%$/.test(s)?100:1),s=s<0?0:s>1?1:s,n){var o=n.split(/\s*;\s*/);""===o[o.length-1]&&o.pop();for(var a=o.length;a--;){var h=o[a].split(/\s*:\s*/),c=h[0].trim(),l=h[1].trim();"stop-color"===c?e=l:"stop-opacity"===c&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:s,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||
 "100%",y2:t.getAttribute("y2")||0}}function i(t){return{x1:t.getAttribute("fx")||t.getAttribute("cx")||"50%",y1:t.getAttribute("fy")||t.getAttribute("cy")||"50%",r1:0,x2:t.getAttribute("cx")||"50%",y2:t.getAttribute("cy")||"50%",r2:t.getAttribute("r")||"50%"}}function r(t,e,i){var r,n=0,s=1,o="";for(var a in e)"Infinity"===e[a]?e[a]=1:"-Infinity"===e[a]&&(e[a]=0),r=parseFloat(e[a],10),s="string"==typeof e[a]&&/^\d+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):"y1"!==a&&"y2"!==a||(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0:0),e[a]=r*s+n;if("ellipse"===t.type&&null!==e.r2&&"objectBoundingBox"===i&&t.rx!==t.ry){var h=t.ry/t.rx;o=" scale(1, "+h+")",e.y1&&(e.y1/=h),e.y2&&(e.y2/=h)}return o}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.Object.__uid++,this.type=t.type||"linear",e={x1:t.coords.x1||0,y1:t.coords
 .y1||0,x2:t.coords.x2||0,y2:t.coords.y2||0},"radial"===this.type&&(e.r1=t.coords.r1||0,e.r2=t.coords.r2||0),this.coords=e,this.colorStops=t.colorStops.slice(),t.gradientTransform&&(this.gradientTransform=t.gradientTransform),this.offsetX=t.offsetX||this.offsetX,this.offsetY=t.offsetY||this.offsetY},addColorStop:function(t){for(var e in t){var i=new fabric.Color(t[e]);this.colorStops.push({offset:e,color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(t){var e={type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform};return fabric.util.populateWithProperties(this,e,t),e},toSVG:function(t){var e,i,r=fabric.util.object.clone(this.coords);if(this.colorStops.sort(function(t,e){return t.offset-e.offset}),!t.group||"path-group"!==t.group.type)for(var n in r)"x1"===n||"x2"===n||"r2"===n?r[n]+=this.offsetX-t.width/2:"y1"!==n&&"y2"!==n|
 |(r[n]+=this.offsetY-t.height/2);i='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(i+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?e=["<linearGradient ",i,' x1="',r.x1,'" y1="',r.y1,'" x2="',r.x2,'" y2="',r.y2,'">\n']:"radial"===this.type&&(e=["<radialGradient ",i,' cx="',r.x2,'" cy="',r.y2,'" r="',r.r2,'" fx="',r.x1,'" fy="',r.y1,'">\n']);for(var s=0;s<this.colorStops.length;s++)e.push("<stop ",'offset="',100*this.colorStops[s].offset+"%",'" style="stop-color:',this.colorStops[s].color,null!==this.colorStops[s].opacity?";stop-opacity: "+this.colorStops[s].opacity:";",'"/>\n');return e.push("linear"===this.type?"</linearGradient>\n":"</radialGradient>\n"),e.join("")},toLive:function(t,e){var i,r,n=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&"path-group"===e.group.type)for(r in n)"x1"===r||"x2"===r?n[r]+=-this.offsetX+e.width/2:"y1"!==r&&"y2"!==r||(n[r]+=-this.offsetY+e.height/2);"linea
 r"===this.type?i=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(i=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2));for(var s=0,o=this.colorStops.length;s<o;s++){var a=this.colorStops[s].color,h=this.colorStops[s].opacity,c=this.colorStops[s].offset;"undefined"!=typeof h&&(a=new fabric.Color(a).setAlpha(h).toRgba()),i.addColorStop(parseFloat(c),a)}return i}}}),fabric.util.object.extend(fabric.Gradient,{fromElement:function(n,s){var o,a,h,c=n.getElementsByTagName("stop"),l=n.getAttribute("gradientUnits")||"objectBoundingBox",u=n.getAttribute("gradientTransform"),f=[];o="linearGradient"===n.nodeName||"LINEARGRADIENT"===n.nodeName?"linear":"radial","linear"===o?a=e(n):"radial"===o&&(a=i(n));for(var d=c.length;d--;)f.push(t(c[d]));h=r(s,a,l);var g=new fabric.Gradient({type:o,coords:a,colorStops:f,offsetX:-s.left,offsetY:-s.top});return(u||""!==h)&&(g.gradientTransform=fabric.parseTransformAttribute((u||"")+h)),g},forObject:function(t,e){return e||(e={}),r(t,e.co
 ords,"userSpaceOnUse"),new fabric.Gradient(e)}})}(),function(){"use strict";var t=fabric.util.toFixed;fabric.Pattern=fabric.util.createClass({repeat:"repeat",offsetX:0,offsetY:0,initialize:function(t,e){if(t||(t={}),this.id=fabric.Object.__uid++,this.setOptions(t),!t.source||t.source&&"string"!=typeof t.source)return void(e&&e(this));if("undefined"!=typeof fabric.util.getFunctionBody(t.source))this.source=new Function(fabric.util.getFunctionBody(t.source)),e&&e(this);else{var i=this;this.source=fabric.util.createImage(),fabric.util.loadImage(t.source,function(t){i.source=t,e&&e(i)})}},toObject:function(e){var i,r,n=fabric.Object.NUM_FRACTION_DIGITS;return"function"==typeof this.source?i=String(this.source):"string"==typeof this.source.src?i=this.source.src:"object"==typeof this.source&&this.source.toDataURL&&(i=this.source.toDataURL()),r={type:"pattern",source:i,repeat:this.repeat,offsetX:t(this.offsetX,n),offsetY:t(this.offsetY,n)},fabric.util.populateWithProperties(this,r,e),r},to
 SVG:function(t){var e="function"==typeof this.source?this.source():this.source,i=e.width/t.width,r=e.height/t.height,n=this.offsetX/t.width,s=this.offsetY/t.height,o="";return"repeat-x"!==this.repeat&&"no-repeat"!==this.repeat||(r=1),"repeat-y"!==this.repeat&&"no-repeat"!==this.repeat||(i=1),e.src?o=e.src:e.toDataURL&&(o=e.toDataURL()),'<pattern id="SVGID_'+this.id+'" x="'+n+'" y="'+s+'" width="'+i+'" height="'+r+'">\n<image x="0" y="0" width="'+e.width+'" height="'+e.height+'" xlink:href="'+o+'"></image>\n</pattern>\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if("undefined"!=typeof e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.toFixed;return e.Shadow?void e.warn("fabric.Shadow is already defined."):(e.Shadow=e.util.createClass({colo
 r:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[],n=i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:n.trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var r=40,n=40,s=e.Object.NUM_FRACTION_DIGITS,o=e.util.rotateVector({x:this.offsetX,y:this.offsetY},e.util.degreesToRadians(-t.angle)),a=20;return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+a,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+a),t.flipX&&(o.x*=-1),t.flipY&&(o.y*=-1),'<filter id="SVGID_'+this.id+'" y="-'+n+'%" height="'+(100+2*n)+'%" x="-'+r+'%" width="'+(100+2*r)+'%" >\n\t<feGaussianBlur in="SourceAlpha" st
 dDeviation="'+i(this.blur?this.blur/2:0,s)+'"></feGaussianBlur>\n\t<feOffset dx="'+i(o.x,s)+'" dy="'+i(o.y,s)+'" result="oBlur" ></feOffset>\n\t<feFlood flood-color="'+this.color+'"/>\n\t<feComposite in2="oBlur" operator="in" />\n\t<feMerge>\n\t\t<feMergeNode></feMergeNode>\n\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n\t</feMerge>\n</filter>\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),void(e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/))}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)return void fabric.warn("fabric.StaticCanvas is already defined.");var t=fabric.util.object.extend,e=fabric.util.get
 ElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=fabric.util.transformPoint,s=fabric.util.invertTransform,o=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!1,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.bac
 kgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=e(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.
 __setBgOverlayColor("backgroundColor",t,e)},_setImageSmoothing:function(){var t=this.getContext();t.imageSmoothingEnabled=t.imageSmoothingEnabled||t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled||t.oImageSmoothingEnabled,t.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(t,e,i,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){e&&(this[t]=new fabric.Image(e,r)),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,i&&i(e)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(t){var e=fabric.util.createCanvasElement(t);if(e.style||(e.style={}),!e)throw o;if("undefined"==typeof e.getContext)throw o;return e},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(t
 his.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(t),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),this},_setBacks
 toreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i=this._activeGroup,r=!1,n=!0;this.viewportTransform=t;for(var s=0,o=this._objects.length;s<o;s++)e=this._objects[s],e.group||e.setCoords(r,n);return i&&i.setCoords(r,n),this.calcViewportBoundaries(),this.renderAll(),this},zoomToPoint:function(t,e){var i=t,r=this.viewportTransform.slice(0);t=n(t,s(this.viewportTransform)),r[0]=e,r[3]=e;var o=n(t,r);return r[4]+=i.x-o.x,r[5]+=i.y-o.y,this.setViewportTransform(r)},setZoom:function(t){return this.zoomToPoint(new fabric.Point(0,0),t),this},absolutePan:function(t){var e=this.viewportTransform.slice(0);return e[4]=-t.
 x,e[5]=-t.y,this.setViewportTransform(e)},relativePan:function(t){return this.absolutePan(new fabric.Point(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))},getElement:function(){return this.lowerCanvasEl},_onObjectAdded:function(t){this.stateful&&t.setupState(),t._set("canvas",this),t.setCoords(),this.fire("object:added",{target:t}),t.fire("added")},_onObjectRemoved:function(t){this.fire("object:removed",{target:t}),t.fire("removed"),delete t.canvas},clearContext:function(t){return t.clearRect(0,0,this.width,this.height),this},getContext:function(){return this.contextContainer},clear:function(){return this._objects.length=0,this.backgroundImage=null,this.overlayImage=null,this.backgroundColor="",this.overlayColor="",this._hasITextHandlers&&(this.off("mouse:up",this._mouseUpITextHandler),this._iTextInstances=null,this._hasITextHandlers=!1),this.clearContext(this.contextContainer),this.fire("canvas:cleared"),this.renderAll(),this},renderAll:function(){var t=this.contex
 tContainer;return this.renderCanvas(t,this._objects),this},calcViewportBoundaries:function(){var t={},e=this.getWidth(),i=this.getHeight(),r=s(this.viewportTransform);return t.tl=n({x:0,y:0},r),t.br=n({x:e,y:i},r),t.tr=new fabric.Point(t.br.x,t.tl.y),t.bl=new fabric.Point(t.tl.x,t.br.y),this.vptCoords=t,t},renderCanvas:function(t,e){this.calcViewportBoundaries(),this.clearContext(t),this.fire("before:render"),this.clipTo&&fabric.util.clipContext(this,t),this._renderBackground(t),t.save(),t.transform.apply(t,this.viewportTransform),this._renderObjects(t,e),t.restore(),!this.controlsAboveOverlay&&this.interactive&&this.drawControls(t),this.clipTo&&t.restore(),this._renderOverlay(t),this.controlsAboveOverlay&&this.interactive&&this.drawControls(t),this.fire("after:render")},_renderObjects:function(t,e){for(var i=0,r=e.length;i<r;++i)e[i]&&e[i].render(t)},_renderBackgroundOrOverlay:function(t,e){var i=this[e+"Color"];i&&(t.fillStyle=i.toLive?i.toLive(t,this):i,t.fillRect(i.offsetX||0,i.
 offsetY||0,this.width,this.height)),i=this[e+"Image"],i&&(this[e+"Vpt"]&&(t.save(),t.transform.apply(t,this.viewportTransform)),
-i.render(t),this[e+"Vpt"]&&t.restore())},_renderBackground:function(t){this._renderBackgroundOrOverlay(t,"background")},_renderOverlay:function(t){this._renderBackgroundOrOverlay(t,"overlay")},getCenter:function(){return{top:this.getHeight()/2,left:this.getWidth()/2}},centerObjectH:function(t){return this._centerObject(t,new fabric.Point(this.getCenter().left,t.getCenterPoint().y))},centerObjectV:function(t){return this._centerObject(t,new fabric.Point(t.getCenterPoint().x,this.getCenter().top))},centerObject:function(t){var e=this.getCenter();return this._centerObject(t,new fabric.Point(e.left,e.top))},viewportCenterObject:function(t){var e=this.getVpCenter();return this._centerObject(t,e)},viewportCenterObjectH:function(t){var e=this.getVpCenter();return this._centerObject(t,new fabric.Point(e.x,t.getCenterPoint().y)),this},viewportCenterObjectV:function(t){var e=this.getVpCenter();return this._centerObject(t,new fabric.Point(t.getCenterPoint().x,e.y))},getVpCenter:function(){var 
 t=this.getCenter(),e=s(this.viewportTransform);return n({x:t.left,y:t.top},e)},_centerObject:function(t,e){return t.setPositionByOrigin(e,"center","center"),this.renderAll(),this},toDatalessJSON:function(t){return this.toDatalessObject(t)},toObject:function(t){return this._toObjectMethod("toObject",t)},toDatalessObject:function(t){return this._toObjectMethod("toDatalessObject",t)},_toObjectMethod:function(e,i){var r={objects:this._toObjects(e,i)};return t(r,this.__serializeBgOverlay(e,i)),fabric.util.populateWithProperties(this,r,i),r},_toObjects:function(t,e){return this.getObjects().filter(function(t){return!t.excludeFromExport}).map(function(i){return this._toObject(i,t,e)},this)},_toObject:function(t,e,i){var r;this.includeDefaultValues||(r=t.includeDefaultValues,t.includeDefaultValues=!1);var n=t[e](i);return this.includeDefaultValues||(t.includeDefaultValues=r),n},__serializeBgOverlay:function(t,e){var i={};return this.backgroundColor&&(i.background=this.backgroundColor.toObje
 ct?this.backgroundColor.toObject(e):this.backgroundColor),this.overlayColor&&(i.overlay=this.overlayColor.toObject?this.overlayColor.toObject(e):this.overlayColor),this.backgroundImage&&(i.backgroundImage=this._toObject(this.backgroundImage,t,e)),this.overlayImage&&(i.overlayImage=this._toObject(this.overlayImage,t,e)),i},svgViewportTransformation:!0,toSVG:function(t,e){t||(t={});var i=[];return this._setSVGPreamble(i,t),this._setSVGHeader(i,t),this._setSVGBgOverlayColor(i,"backgroundColor"),this._setSVGBgOverlayImage(i,"backgroundImage",e),this._setSVGObjects(i,e),this._setSVGBgOverlayColor(i,"overlayColor"),this._setSVGBgOverlayImage(i,"overlayImage",e),i.push("</svg>"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('<?xml version="1.0" encoding="',e.encoding||"UTF-8",'" standalone="no" ?>\n','<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ','"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.h
 eight||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("<svg ",'xmlns="http://www.w3.org/2000/svg" ','xmlns:xlink="http://www.w3.org/1999/xlink" ','version="1.1" ','width="',n,'" ','height="',s,'" ',o,'xml:space="preserve">\n',"<desc>Created with Fabric.js ",fabric.version,"</desc>\n","<defs>\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),"</defs>\n")},createSVGRefElementsMarkup:function(){var t=this,e=["backgroundColor","overlayColor"].map(function(e){var i=t[e];if(i&&i.toLive)return i.toSVG(t,!1)});return e.join("")},createSVGFontFacesMarkup:function(){for(var t,e,i,r,n,s,o,a="",h={},c=fabric.fontPaths,l=this.getObjects(),u=0,f=l.length;u<f;u++)
 if(t=l[u],e=t.fontFamily,t.type.indexOf("text")!==-1&&!h[e]&&c[e]&&(h[e]=!0,t.styles)){i=t.styles;for(n in i){r=i[n];for(o in r)s=r[o],e=s.fontFamily,!h[e]&&c[e]&&(h[e]=!0)}}for(var d in h)a+=["\t\t@font-face {\n","\t\t\tfont-family: '",d,"';\n","\t\t\tsrc: url('",c[d],"');\n","\t\t}\n"].join("");return a&&(a=['\t<style type="text/css">',"<![CDATA[\n",a,"]]>","</style>\n"].join("")),a},_setSVGObjects:function(t,e){for(var i,r=0,n=this.getObjects(),s=n.length;r<s;r++)i=n[r],i.excludeFromExport||this._setSVGObject(t,i,e)},_setSVGObject:function(t,e,i){t.push(e.toSVG(i))},_setSVGBgOverlayImage:function(t,e,i){this[e]&&this[e].toSVG&&t.push(this[e].toSVG(i))},_setSVGBgOverlayColor:function(t,e){var i=this[e];if(i)if(i.toLive){var r=i.repeat;t.push('<rect transform="translate(',this.width/2,",",this.height/2,')"',' x="',i.offsetX-this.width/2,'" y="',i.offsetY-this.height/2,'" ','width="',"repeat-y"===r||"no-repeat"===r?i.source.width:this.width,'" height="',"repeat-x"===r||"no-repeat"==
 =r?i.source.height:this.height,'" fill="url(#SVGID_'+i.id+')"',"></rect>\n")}else t.push('<rect x="0" y="0" ','width="',this.width,'" height="',this.height,'" fill="',this[e],'"',"></rect>\n")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=n.length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll()},bringToFront:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=0;e<n.length;e++)r=n[e],i(this._objects,r),this._objects.push(r);else i(this._objects,t),this._objects.push(t);return this.renderAll&&this.renderAll()},sendBackwards:function(t,e){if(!t)return this;var r,n,s,o,a,h=this._activeGroup;if(t===h)for(a=h._objects,r=0;r<a.length;r++)n=a[r],s=this._objects.indexOf(n),0!==s&&(o=s-1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),0!==s&&(o=this._findNewLowerIndex(t,s,e),i(
 this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewLowerIndex:function(t,e,i){var r;if(i){r=e;for(var n=e-1;n>=0;--n){var s=t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t);if(s){r=n;break}}}else r=e-1;return r},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,h=this._activeGroup;if(t===h)for(a=h._objects,r=a.length;r--;)n=a[r],s=this._objects.indexOf(n),s!==this._objects.length-1&&(o=s+1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),s!==this._objects.length-1&&(o=this._findNewUpperIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewUpperIndex:function(t,e,i){var r;if(i){r=e;for(var n=e+1;n<this._objects.length;++n){var s=t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t
 );if(s){r=n;break}}}else r=e+1;return r},moveTo:function(t,e){return i(this._objects,t),this._objects.splice(e,0,t),this.renderAll&&this.renderAll()},dispose:function(){return this.clear(),this},toString:function(){return"#<fabric.Canvas ("+this.complexity()+"): { objects: "+this.getObjects().length+" }>"}}),t(fabric.StaticCanvas.prototype,fabric.Observable),t(fabric.StaticCanvas.prototype,fabric.Collection),t(fabric.StaticCanvas.prototype,fabric.DataURLExporter),t(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=fabric.util.createCanvasElement();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"getImageData":return"undefined"!=typeof i.getImageData;case"setLineDash":return"undefined"!=typeof i.setLineDash;case"toDataURL":return"undefined"!=typeof e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(t){}return!1;default:return null}}}),fabric.StaticCanvas.pro
 totype.toJSON=fabric.StaticCanvas.prototype.toObject}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(t){return this.shadow=new fabric.Shadow(t),this},_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")&&t.setLineDash(this.strokeDashArray)},_setShadow:function(){if(this.shadow){var t=this.canvas.contextTop,e=this.canvas.getZoom();t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*e,t.shadowOffsetX=this.shadow.offsetX*e,t.shadowOffsetY=this.shadow.offsetY*e}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(t){this.can
 vas=t,this._points=[]},onMouseDown:function(t){this._prepareForDrawing(t),this._captureDrawingPath(t),this._render()},onMouseMove:function(t){this._captureDrawingPath(t),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(t){var e=new fabric.Point(t.x,t.y);this._reset(),this._addPoint(e),this.canvas.contextTop.moveTo(e.x,e.y)},_addPoint:function(t){this._points.push(t)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(t){var e=new fabric.Point(t.x,t.y);this._addPoint(e)},_render:function(){var t=this.canvas.contextTop,e=this.canvas.viewportTransform,i=this._points[0],r=this._points[1];t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]),t.beginPath(),2===this._points.length&&i.x===r.x&&i.y===r.y&&(i.x-=.5,r.x+=.5),t.moveTo(i.x,i.y);for(var n=1,s=this._points.length;n<s;n++){var o=i.midPointFrom(r);t.quadraticCurveTo(i.x,i.y,o.x,o.y),i
 =this._points[n],r=this._points[n+1]}t.lineTo(i.x,i.y),t.stroke(),t.restore()},convertPointsToSVGPath:function(t){var e=[],i=new fabric.Point(t[0].x,t[0].y),r=new fabric.Point(t[1].x,t[1].y);e.push("M ",t[0].x," ",t[0].y," ");for(var n=1,s=t.length;n<s;n++){var o=i.midPointFrom(r);e.push("Q ",i.x," ",i.y," ",o.x," ",o.y," "),i=new fabric.Point(t[n].x,t[n].y),n+1<t.length&&(r=new fabric.Point(t[n+1].x,t[n+1].y))}return e.push("L ",i.x," ",i.y," "),e},createPath:function(t){var e=new fabric.Path(t,{fill:null,stroke:this.color,strokeWidth:this.width,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeDashArray:this.strokeDashArray,originX:"center",originY:"center"});return this.shadow&&(this.shadow.affectStroke=!0,e.setShadow(this.shadow)),e},_finalizeAndAddPath:function(){var t=this.canvas.contextTop;t.closePath();var e=this.convertPointsToSVGPath(this._points).join("");if("M 0 0 Q 0 0 0 0 L 0 0"===e)return void this.canvas.renderAll();var i=this.createPath(e);th
 is.canvas.add(i),i.setCoords(),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderAll(),this.canvas.fire("path:created",{path:i})}})}(),fabric.CircleBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,initialize:function(t){this.canvas=t,this.points=[]},drawDot:function(t){var e=this.addPoint(t),i=this.canvas.contextTop,r=this.canvas.viewportTransform;i.save(),i.transform(r[0],r[1],r[2],r[3],r[4],r[5]),i.fillStyle=e.fill,i.beginPath(),i.arc(e.x,e.y,e.radius,0,2*Math.PI,!1),i.closePath(),i.fill(),i.restore()},onMouseDown:function(t){this.points.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.drawDot(t)},onMouseMove:function(t){this.drawDot(t)},onMouseUp:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.points.length;i<r;i++){var n=this.points[i],s=new fabric.Circle({radius:n.radius,left:n.x,top:n.y,originX:"center",originY:"center",fill:n.fill});this.shadow&
 &s.setShadow(this.shadow),e.push(s)}var o=new fabric.Group(e,{originX:"center",originY:"center"});o.canvas=this.canvas,this.canvas.add(o),this.canvas.fire("path:created",{path:o}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},addPoint:function(t){var e=new fabric.Point(t.x,t.y),i=fabric.util.getRandomInt(Math.max(0,this.width-20),this.width+20)/2,r=new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0,100)/100).toRgba();return e.radius=i,e.fill=r,this.points.push(e),e}}),fabric.SprayBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,density:20,dotWidth:1,dotWidthVariance:1,randomOpacity:!1,optimizeOverlapping:!0,initialize:function(t){this.canvas=t,this.sprayChunks=[]},onMouseDown:function(t){this.sprayChunks.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.addSprayChunk(t),this.render()},onMouseMove:function(t){this.addSprayChunk(t),this.render()},onMouse
 Up:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.sprayChunks.length;i<r;i++)for(var n=this.sprayChunks[i],s=0,o=n.length;s<o;s++){var a=new fabric.Rect({width:n[s].width,height:n[s].width,left:n[s].x+1,top:n[s].y+1,originX:"center",originY:"center",fill:this.color});this.shadow&&a.setShadow(this.shadow),e.push(a)}this.optimizeOverlapping&&(e=this._getOptimizedRects(e));var h=new fabric.Group(e,{originX:"center",originY:"center"});h.canvas=this.canvas,this.canvas.add(h),this.canvas.fire("path:created",{path:h}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},_getOptimizedRects:function(t){for(var e,i={},r=0,n=t.length;r<n;r++)e=t[r].left+""+t[r].top,i[e]||(i[e]=t[r]);var s=[];for(e in i)s.push(i[e]);return s},render:function(){var t=this.canvas.contextTop;t.fillStyle=this.color;var e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e
 [3],e[4],e[5]);for(var i=0,r=this.sprayChunkPoints.length;i<r;i++){var n=this.sprayChunkPoints[i];"undefined"!=typeof n.opacity&&(t.globalAlpha=n.opacity),t.fillRect(n.x,n.y,n.width,n.width)}t.restore()},addSprayChunk:function(t){this.sprayChunkPoints=[];for(var e,i,r,n=this.width/2,s=0;s<this.density;s++){e=fabric.util.getRandomInt(t.x-n,t.x+n),i=fabric.util.getRandomInt(t.y-n,t.y+n),r=this.dotWidthVariance?fabric.util.getRandomInt(Math.max(1,this.dotWidth-this.dotWidthVariance),this.dotWidth+this.dotWidthVariance):this.dotWidth;var o=new fabric.Point(e,i);o.width=r,this.randomOpacity&&(o.opacity=fabric.util.getRandomInt(0,100)/100),this.sprayChunkPoints.push(o)}this.sprayChunks.push(this.sprayChunkPoints)}}),fabric.PatternBrush=fabric.util.createClass(fabric.PencilBrush,{getPatternSrc:function(){var t=20,e=5,i=fabric.document.createElement("canvas"),r=i.getContext("2d");return i.width=i.height=t+e,r.fillStyle=this.color,r.beginPath(),r.arc(t/2,t/2,t/2,0,2*Math.PI,!1),r.closePath()
 ,r.fill(),i},getPatternSrcFunction:function(){return String(this.getPatternSrc).replace("this.color",'"'+this.color+'"')},getPattern:function(){return this.canvas.contextTop.createPattern(this.source||this.getPatternSrc(),"repeat")},_setBrushStyles:function(){this.callSuper("_setBrushStyles"),this.canvas.contextTop.strokeStyle=this.getPattern()},createPath:function(t){var e=this.callSuper("createPath",t),i=e._getLeftTopCoords().scalarAdd(e.strokeWidth/2);return e.stroke=new fabric.Pattern({source:this.source||this.getPatternSrcFunction(),offsetX:-i.x,offsetY:-i.y}),e}}),function(){var t=fabric.util.getPointer,e=fabric.util.degreesToRadians,i=fabric.util.radiansToDegrees,r=Math.atan2,n=Math.abs,s=fabric.StaticCanvas.supports("setLineDash"),o=.5;fabric.Canvas=fabric.util.createClass(fabric.StaticCanvas,{initialize:function(t,e){e||(e={}),this._initStatic(t,e),this._initInteractive(),this._createCacheCanvas()},uniScaleTransform:!1,uniScaleKey:"shiftKey",centeredScaling:!1,centeredRotat
 ion:!1,centeredKey:"altKey",altActionKey:"shiftKey",interactive:!0,selection:!0,selectionKey:"shiftKey",altSelectionKey:null,selectionColor:"rgba(100, 100, 255, 0.3)",selectionDashArray:[],selectionBorderColor:"rgba(255, 255, 255, 0.3)",selectionLineWidth:1,hoverCursor:"move",moveCursor:"move",defaultCursor:"default",freeDrawingCursor:"crosshair",rotationCursor:"crosshair",containerClass:"canvas-container",perPixelTargetFind:!1,targetFindTolerance:0,skipTargetFind:!1,isDrawingMode:!1,preserveObjectStacking:!1,snapAngle:0,snapThreshold:null,stopContextMenu:!1,fireRightClick:!1,fireMiddleClick:!1,_initInteractive:function(){this._currentTransform=null,this._groupSelector=null,this._initWrapperElement(),this._createUpperCanvas(),this._initEventListeners(),this._initRetinaScaling(),this.freeDrawingBrush=fabric.PencilBrush&&new fabric.PencilBrush(this),this.calcOffset()},_chooseObjectsToRender:function(){var t,e=this.getActiveGroup(),i=this.getActiveObject(),r=[],n=[];if(!e&&!i||this.pre
 serveObjectStacking)r=this._objects;else{for(var s=0,o=this._objects.length;s<o;s++)t=this._objects[s],e&&e.contains(t)||t===i?n.push(t):r.push(t);e&&(e._set("_objects",n),r.push(e)),i&&r.push(i)}return r},renderAll:function(){!this.contextTopDirty||this._groupSelector||this.isDrawingMode||(this.clearContext(this.contextTop),this.contextTopDirty=!1);var t=this.contextContainer;return this.renderCanvas(t,this._chooseObjectsToRender()),this},renderTop:function(){var t=this.contextTop;return this.clearContext(t),this.selection&&this._groupSelector&&this._drawSelection(t),this.fire("after:render"),this.contextTopDirty=!0,this},_resetCurrentTransform:function(){var t=this._currentTransform;t.target.set({scaleX:t.original.scaleX,scaleY:t.original.scaleY,skewX:t.original.skewX,skewY:t.original.skewY,left:t.original.left,top:t.original.top}),this._shouldCenterTransform(t.target)?"rotate"===t.action?this._setOriginToCenter(t.target):("center"!==t.originX&&("right"===t.originX?t.mouseXSign=-1
 :t.mouseXSign=1),"center"!==t.originY&&("bottom"===t.originY?t.mouseYSign=-1:t.mouseYSign=1),t.originX="center",t.originY="center"):(t.originX=t.original.originX,t.originY=t.original.originY)},containsPoint:function(t,e,i){var r,n=!0,s=i||this.getPointer(t,n);return r=e.group&&e.group===this.getActiveGroup()?this._normalizePointer(e.group,s):{x:s.x,y:s.y},e.containsPoint(r)||e._findTargetCorner(s)},_normalizePointer:function(t,e){var i=t.calcTransformMatrix(),r=fabric.util.invertTransform(i),n=this.restorePointerVpt(e);return fabric.util.transformPoint(n,r)},isTargetTransparent:function(t,e,i){var r=t.hasBorders,n=t.transparentCorners,s=this.contextCache,o=t.selectionBackgroundColor;t.hasBorders=t.transparentCorners=!1,t.selectionBackgroundColor="",s.save(),s.transform.apply(s,this.viewportTransform),t.render(s),s.restore(),t.active&&t._renderControls(s),t.hasBorders=r,t.transparentCorners=n,t.selectionBackgroundColor=o;var a=fabric.util.isTransparent(s,e,i,this.targetFindTolerance)
 ;return this.clearContext(s),a},_shouldClearSelection:function(t,e){var i=this.getActiveGroup(),r=this.getActiveObject();return!e||e&&i&&!i.contains(e)&&i!==e&&!t[this.selectionKey]||e&&!e.evented||e&&!e.selectable&&r&&r!==e},_shouldCenterTransform:function(t){if(t){var e,i=this._currentTransform;return"scale"===i.action||"scaleX"===i.action||"scaleY"===i.action?e=this.centeredScaling||t.centeredScaling:"rotate"===i.action&&(e=this.centeredRotation||t.centeredRotation),e?!i.altKey:i.altKey}},_getOriginFromCorner:function(t,e){var i={x:t.originX,y:t.originY};return"ml"===e||"tl"===e||"bl"===e?i.x="right":"mr"!==e&&"tr"!==e&&"br"!==e||(i.x="left"),"tl"===e||"mt"===e||"tr"===e?i.y="bottom":"bl"!==e&&"mb"!==e&&"br"!==e||(i.y="top"),i},_getActionFromCorner:function(t,e,i){if(!e)return"drag";switch(e){case"mtr":return"rotate";case"ml":case"mr":return i[this.altActionKey]?"skewY":"scaleX";case"mt":case"mb":return i[this.altActionKey]?"skewX":"scaleY";default:return"scale"}},_setupCurrentTr
 ansform:function(t,i){if(i){var r=this.getPointer(t),n=i._findTargetCorner(this.getPointer(t,!0)),s=this._getActionFromCorner(i,n,t),o=this._getOriginFromCorner(i,n);this._currentTransform={target:i,action:s,corner:n,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,offsetX:r.x-i.left,offsetY:r.y-i.top,originX:o.x,originY:o.y,ex:r.x,ey:r.y,lastX:r.x,lastY:r.y,left:i.left,top:i.top,theta:e(i.angle),width:i.width*i.scaleX,mouseXSign:1,mouseYSign:1,shiftKey:t.shiftKey,altKey:t[this.centeredKey]},this._currentTransform.original={left:i.left,top:i.top,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,originX:o.x,originY:o.y},this._resetCurrentTransform()}},_translateObject:function(t,e){var i=this._currentTransform,r=i.target,n=t-i.offsetX,s=e-i.offsetY,o=!r.get("lockMovementX")&&r.left!==n,a=!r.get("lockMovementY")&&r.top!==s;return o&&r.set("left",n),a&&r.set("top",s),o||a},_changeSkewTransformOrigin:function(t,e,i){var r="originX",n={0:"center"},s=e.target.skewX,o=
 "left",a="right",h="mt"===e.corner||"ml"===e.corner?1:-1,c=1;t=t>0?1:-1,"y"===i&&(s=e.target.skewY,o="top",a="bottom",r="originY"),n[-1]=o,n[1]=a,e.target.flipX&&(c*=-1),e.target.flipY&&(c*=-1),0===s?(e.skewSign=-h*t*c,e[r]=n[-t]):(s=s>0?1:-1,e.skewSign=s,e[r]=n[s*h*c])},_skewObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=!1,o=n.get("lockSkewingX"),a=n.get("lockSkewingY");if(o&&"x"===i||a&&"y"===i)return!1;var h,c,l=n.getCenterPoint(),u=n.toLocalPoint(new fabric.Point(t,e),"center","center")[i],f=n.toLocalPoint(new fabric.Point(r.lastX,r.lastY),"center","center")[i],d=n._getTransformedDimensions();return this._changeSkewTransformOrigin(u-f,r,i),h=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY)[i],c=n.translateToOriginPoint(l,r.originX,r.originY),s=this._setObjectSkew(h,r,i,d),r.lastX=t,r.lastY=e,n.setPositionByOrigin(c,r.originX,r.originY),s},_setObjectSkew:function(t,e,i,r){var n,s,o,a,h,c,l,u,f,d=e.target,g=!1,p=e.skewSign;return"x"===i?(a="y",h="Y",c="
 X",u=0,f=d.skewY):(a="x",h="X",c="Y",u=d.skewX,f=0),o=d._getTransformedDimensions(u,f),l=2*Math.abs(t)-o[i],l<=2?n=0:(n=p*Math.atan(l/d["scale"+c]/(o[a]/d["scale"+h])),n=fabric.util.radiansToDegrees(n)),g=d["skew"+c]!==n,d.set("skew"+c,n),0!==d["skew"+h]&&(s=d._getTransformedDimensions(),n=r[a]/s[a]*d["scale"+h],d.set("scale"+h,n)),g},_scaleObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=n.get("lockScalingX"),o=n.get("lockScalingY"),a=n.get("lockScalingFlip");if(s&&o)return!1;var h=n.translateToOriginPoint(n.getCenterPoint(),r.originX,r.originY),c=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY),l=n._getTransformedDimensions(),u=!1;return this._setLocalMouse(c,r),u=this._setObjectScale(c,r,s,o,i,a,l),n.setPositionByOrigin(h,r.originX,r.originY),u},_setObjectScale:function(t,e,i,r,n,s,o){var a,h,c,l,u=e.target,f=!1,d=!1,g=!1;return c=t.x*u.scaleX/o.x,l=t.y*u.scaleY/o.y,a=u.scaleX!==c,h=u.scaleY!==l,s&&c<=0&&c<u.scaleX&&(f=!0),s&&l<=0&&l<u.scaleY&&(d=!0),"equ
 ally"!==n||i||r?n?"x"!==n||u.get("lockUniScaling")?"y"!==n||u.get("lockUniScaling")||d||r||u.set("scaleY",l)&&(g=g||h):f||i||u.set("scaleX",c)&&(g=g||a):(f||i||u.set("scaleX",c)&&(g=g||a),d||r||u.set("scaleY",l)&&(g=g||h)):f||d||(g=this._scaleObjectEqually(t,u,e,o)),e.newScaleX=c,e.newScaleY=l,f||d||this._flipObject(e,n),g},_scaleObjectEqually:function(t,e,i,r){var n,s=t.y+t.x,o=r.y*i.original.scaleY/e.scaleY+r.x*i.original.scaleX/e.scaleX;return i.newScaleX=i.original.scaleX*s/o,i.newScaleY=i.original.scaleY*s/o,n=i.newScaleX!==e.scaleX||i.newScaleY!==e.scaleY,e.set("scaleX",i.newScaleX),e.set("scaleY",i.newScaleY),n},_flipObject:function(t,e){t.newScaleX<0&&"y"!==e&&("left"===t.originX?t.originX="right":"right"===t.originX&&(t.originX="left")),t.newScaleY<0&&"x"!==e&&("top"===t.originY?t.originY="bottom":"bottom"===t.originY&&(t.originY="top"))},_setLocalMouse:function(t,e){var i=e.target,r=this.getZoom(),s=i.padding/r;"right"===e.originX?t.x*=-1:"center"===e.originX&&(t.x*=2*e.mo
 useXSign,t.x<0&&(e.mouseXSign=-e.mouseXSign)),"bottom"===e.originY?t.y*=-1:"center"===e.originY&&(t.y*=2*e.mouseYSign,t.y<0&&(e.mouseYSign=-e.mouseYSign)),n(t.x)>s?t.x<0?t.x+=s:t.x-=s:t.x=0,n(t.y)>s?t.y<0?t.y+=s:t.y-=s:t.y=0},_rotateObject:function(t,e){var n=this._currentTransform;if(n.target.get("lockRotation"))return!1;var s=r(n.ey-n.top,n.ex-n.left),o=r(e-n.top,t-n.left),a=i(o-s+n.theta),h=!0;if(a<0&&(a=360+a),a%=360,n.target.snapAngle>0){var c=n.target.snapAngle,l=n.target.snapThreshold||c,u=Math.ceil(a/c)*c,f=Math.floor(a/c)*c;Math.abs(a-f)<l?a=f:Math.abs(a-u)<l&&(a=u),n.target.angle===a&&(h=!1)}return n.target.angle=a,h},setCursor:function(t){this.upperCanvasEl.style.cursor=t},_resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.setAngle(0)},_drawSelection:function(t){var e=this._groupSelector,i=e.left,r=e.top,a=n(i),h=n(r

<TRUNCATED>

[42/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1634] drag to trash should work better

Posted by so...@apache.org.
[OPENMEETINGS-1634] drag to trash should work better


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/bb416460
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/bb416460
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/bb416460

Branch: refs/heads/master
Commit: bb4164604aaf4b354bde83714670065d3ffa6890
Parents: 876e088
Author: Maxim Solodovnik <so...@apache.org>
Authored: Wed Apr 19 14:52:21 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Wed Apr 19 14:52:21 2017 +0000

----------------------------------------------------------------------
 .../org/apache/openmeetings/web/common/tree/FileTreePanel.html | 6 +++---
 .../org/apache/openmeetings/web/common/tree/FolderPanel.java   | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bb416460/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html
index 36ef583..9e38d57 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html
@@ -27,9 +27,9 @@
 			if (s.parents('a').hasClass('ui-state-active')) {
 				s = $('.ui-state-active .ui-draggable.ui-draggable-handle');
 			}
-			var c = $('<div/>').attr('id', 'draggingContainer');
-			c.append(s.clone());
-			return c;
+			var c = $('<div/>').attr('id', 'draggingContainer').width(80).height(36);
+			var h = $('<div class="ui-corner-all ui-widget-header"/>').append(s.clone()).width(s.width());
+			return c.append(h);
 		}
 		function treeRevert(dropped) {
 			$('.file.tree .trees')[0].scrollTop = $(this).parent()[0].offsetTop - 32;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bb416460/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FolderPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FolderPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FolderPanel.java
index fdc60b4..7e685a7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FolderPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FolderPanel.java
@@ -91,6 +91,7 @@ public class FolderPanel extends Panel {
 					behavior.setOption("revert", "treeRevert");
 					behavior.setOption("cursor", Options.asString("move"));
 					behavior.setOption("helper", "dragHelper");
+					behavior.setOption("cursorAt", "{left: 40, top: 18}");
 				}
 			}.setContainment(treePanel.getContainment());
 			String cls = r instanceof Recording ? "recorditem" : "fileitem";


[17/50] [abbrv] openmeetings git commit: [OPENMEETINGS-1612, OPENMEETINGS-980] tomcat version is corrected

Posted by so...@apache.org.
[OPENMEETINGS-1612, OPENMEETINGS-980] tomcat version is corrected


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/d8febfd8
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/d8febfd8
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/d8febfd8

Branch: refs/heads/master
Commit: d8febfd816ebaa729680c6a461902c97f6b7e58e
Parents: d8a5a80
Author: Maxim Solodovnik <so...@apache.org>
Authored: Thu Apr 6 12:20:17 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Thu Apr 6 12:20:17 2017 +0000

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/d8febfd8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ce0e527..70f13c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,7 +47,7 @@
 		<red5-client.version>1.0.9-M6</red5-client.version>
 		<spring.version>4.3.6.RELEASE</spring.version>
 		<mina.version>2.0.16</mina.version>
-		<tomcat.version>8.5.11</tomcat.version>
+		<tomcat.version>8.5.12</tomcat.version>
 		<ical4j.version>2.0.0</ical4j.version>
 		<cxf.version>3.1.9</cxf.version>
 		<selenium.version>3.0.1</selenium.version>


[46/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] existing video streams are being played on room enter

Posted by so...@apache.org.
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Client.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Client.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Client.java
deleted file mode 100644
index 1fc7406..0000000
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Client.java
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * 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.db.entity.room;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.apache.openmeetings.db.entity.basic.IClient;
-import org.apache.openmeetings.db.entity.server.Server;
-import org.apache.openmeetings.util.CalendarPatterns;
-
-/**
- * Can be configured to be stored in memory or in database
- *
- * @author sebawagner
- */
-@Entity
-@NamedQueries({
-	@NamedQuery(name = "deleteAll", query = "DELETE FROM Client"),
-	@NamedQuery(name = "deletedById", query = "DELETE FROM Client c WHERE c.id = :id"),
-	@NamedQuery(name = "deleteClientsByServer", query = "DELETE FROM Client c WHERE c.server = :server"),
-	@NamedQuery(name = "deletedByServerAndStreamId", query = "DELETE FROM Client c WHERE c.server = :server AND c.streamid LIKE :streamid"),
-	@NamedQuery(name = "countClients", query = "SELECT count(c.id) FROM Client c"),
-	@NamedQuery(name = "countClientsByServer", query = "SELECT count(c.id) FROM Client c WHERE c.server = :server"),
-	@NamedQuery(name = "countClientsByServerAndStreamId", query = "SELECT count(c.id) FROM Client c WHERE c.streamid LIKE :streamid AND c.server = :server"),
-	@NamedQuery(name = "getClientByServerAndStreamId", query = "SELECT c FROM Client c WHERE c.streamid LIKE :streamid AND c.server = :server"),
-	@NamedQuery(name = "getClientsByPublicSIDAndServer", query = "SELECT c FROM Client c WHERE c.publicSID LIKE :publicSID AND c.server = :server"),
-	@NamedQuery(name = "getClientsByPublicSID", query = "SELECT c FROM Client c WHERE c.publicSID LIKE :publicSID"),
-	@NamedQuery(name = "getClientsByServer", query = "SELECT c FROM Client c WHERE c.server = :server"),
-	@NamedQuery(name = "getClients", query = "SELECT c FROM Client c"),
-	@NamedQuery(name = "getClientsWithServer", query = "SELECT c FROM Client c LEFT JOIN FETCH c.server"),
-	@NamedQuery(name = "getClientsByUserId", query = "SELECT c FROM Client c WHERE c.server = :server AND c.userId = :userId"),
-	@NamedQuery(name = "getClientsByRoomId", query = "SELECT c FROM Client c WHERE c.roomId = :roomId"),
-	@NamedQuery(name = "getRoomsIdsByServer", query = "SELECT c.roomId FROM Client c WHERE c.server = :server GROUP BY c.roomId")
-})
-@Table(name = "client")
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-public class Client implements IClient {
-	private static final long serialVersionUID = 1L;
-
-	@Id
-	@GeneratedValue(strategy = GenerationType.IDENTITY)
-	@Column(name = "id")
-	private Long id;
-
-	/**
-	 * @see Client#getUsername()
-	 */
-	@Column(name = "username")
-	private String username = "";
-
-	/**
-	 * @see Client#getStreamid()
-	 */
-	@Column(name = "streamid")
-	private String streamid = "";
-
-	/**
-	 * @see Client#getScope()
-	 */
-	@Column(name = "scope")
-	private String scope = "";
-
-	/**
-	 * @see Client#getVWidth()
-	 */
-	@Column(name = "vwidth")
-	private int vWidth = 0;
-
-	/**
-	 * @see Client#getVHeight()
-	 */
-	@Column(name = "vheight")
-	private int vHeight = 0;
-
-	/**
-	 * @see Client#getVX()
-	 */
-	@Column(name = "vx")
-	private int vX = 0;
-
-	/**
-	 * @see Client#getVY()
-	 */
-	@Column(name = "vy")
-	private int vY = 0;
-
-	/**
-	 * @see Client#getStreamPublishName()
-	 */
-	@Column(name = "stream_publish_name")
-	private String streamPublishName = "";
-
-	/**
-	 * @see Client#getPublicSID()
-	 */
-	@Column(name = "public_sid")
-	private String publicSID = "";
-
-	/**
-	 * @see Client#getIsMod()
-	 */
-	@Column(name = "is_mod", nullable = false)
-	private boolean isMod = false;
-
-	/**
-	 * @see Client#getIsSuperModerator()
-	 */
-	@Column(name = "is_supermoderator", nullable = false)
-	private boolean isSuperModerator = false;
-
-	/**
-	 * @see Client#getCanDraw()
-	 */
-	@Column(name = "can_draw", nullable = false)
-	private boolean canDraw = false;
-
-	/**
-	 * @see Client#getCanShare()
-	 */
-	@Column(name = "can_share", nullable = false)
-	private boolean canShare = false;
-
-	/**
-	 * @see Client#getCanRemote()
-	 */
-	@Column(name = "can_remote", nullable = false)
-	private boolean canRemote = false;
-
-	/**
-	 * @see Client#getCanGiveAudio()
-	 */
-	@Column(name = "can_giveaudio", nullable = false)
-	private boolean canGiveAudio = false;
-
-	@Column(name = "can_video", nullable = false)
-	private boolean canVideo = false;
-
-	/**
-	 * @see Client#getConnectedSince()
-	 */
-	@Column(name = "connected_since")
-	private Date connectedSince;
-
-	/**
-	 * @see Client#getFormatedDate()
-	 */
-	@Column(name = "formated_date")
-	private String formatedDate;
-
-	/**
-	 * @see Client#isScreenClient()
-	 */
-	@Column(name = "is_screenclient", nullable = false)
-	private boolean screenClient;
-
-	/**
-	 * @see Client#getUsercolor()
-	 */
-	@Column(name = "usercolor")
-	private String usercolor;
-
-	/**
-	 * @see Client#getUserpos()
-	 */
-	@Column(name = "userpos")
-	private Integer userpos;
-
-	/**
-	 * @see Client#getUserip()
-	 */
-	@Column(name = "userip")
-	private String userip;
-
-	/**
-	 * @see Client#getUserport()
-	 */
-	@Column(name = "userport")
-	private int userport;
-
-	/**
-	 * @see Client#getRoomId()
-	 */
-	@Column(name = "room_id")
-	private Long roomId;
-
-	/**
-	 * @see Client#getRoomEnter()
-	 */
-	@Column(name = "room_enter")
-	private Date roomEnter = null;
-
-	/**
-	 * @see Client#getBroadCastID()
-	 */
-	@Column(name = "broadcast_id")
-	private long broadCastID = -2;
-
-	/**
-	 * @see Client#getUserId()
-	 */
-	@Column(name = "user_id")
-	private Long userId = null;
-
-	/**
-	 * @see Client#getFirstname()
-	 */
-	@Column(name = "firstname")
-	private String firstname = "";
-
-	/**
-	 * @see Client#getLastname()
-	 */
-	@Column(name = "lastname")
-	private String lastname = "";
-
-	/**
-	 * @see Client#getMail()
-	 */
-	@Column(name = "email")
-	private String email;
-
-	/**
-	 * @see Client#getLastLogin()
-	 */
-	@Column(name = "last_login")
-	private String lastLogin;
-
-	/**
-	 * @see Client#getSecurityCode()
-	 */
-	@Column(name = "security_code")
-	private String securityCode;
-
-	/**
-	 * @see Client#getPicture_uri()
-	 */
-	@Column(name = "picture_uri")
-	private String picture_uri;
-
-	/**
-	 * @see Client#getLanguage()
-	 */
-	@Column(name = "language")
-	private String language = "";
-
-	/**
-	 * @see Client#getAvsettings()
-	 */
-	@Column(name = "avsettings")
-	private String avsettings = "";
-
-	/**
-	 * @see Client#getSwfurl()
-	 */
-	// FIXME: Move to {@link ClientSession}
-	@Column(name = "swfurl", length=2048)
-	private String swfurl;
-
-	@Column(name = "tcurl", length=2048)
-	private String tcUrl;
-
-	@Column(name = "nativeSsl", nullable = false)
-	private boolean nativeSsl = false;
-
-	/**
-	 * @see Client#getIsRecording()
-	 */
-	@Column(name = "is_recording", nullable = false)
-	private boolean isRecording = false;
-
-	/**
-	 * @see Client#getRoomRecordingName()
-	 */
-	@Column(name = "room_recording_name")
-	private String roomRecordingName;
-
-	/**
-	 * @see Client#getRecordingId()
-	 */
-	@Column(name = "recording_id")
-	private Long recordingId;
-
-	/**
-	 * @see Client#getRecordingMetaDataId()
-	 */
-	@Column(name = "recording_metadata_id")
-	private Long recordingMetaDataId;
-
-	/**
-	 * @see Client#isStartRecording()
-	 */
-	@Column(name = "start_recording", nullable = false)
-	private boolean startRecording = false;
-
-	/**
-	 * @see Client#isStartStreaming()
-	 */
-	@Column(name = "start_streaming", nullable = false)
-	private boolean startStreaming = false;
-
-	/**
-	 * @see Client#isScreenPublishStarted()
-	 */
-	@Column(name = "screen_publish_started", nullable = false)
-	private boolean screenPublishStarted = false;
-
-	/**
-	 * @see Client#isStreamPublishStarted()
-	 */
-	@Column(name = "stream_publish_started", nullable = false)
-	private boolean streamPublishStarted = false;
-
-	/**
-	 * @see Client#getIsBroadcasting()
-	 */
-	@Column(name = "is_broadcasting", nullable = false)
-	private boolean isBroadcasting = false;
-
-	/**
-	 * @see Client#getExternalUserId()
-	 */
-	@Column(name = "external_user_id")
-	private String externalUserId;
-
-	/**
-	 * @see Client#getExternalUserType()
-	 */
-	@Column(name = "external_user_type")
-	private String externalUserType;
-
-	/**
-	 * @see Client#getInterviewPodId()
-	 */
-	@Column(name = "interview_pod_id")
-	private Integer interviewPodId = null;
-
-	/**
-	 * @see Client#isAllowRecording()
-	 */
-	@Column(name = "allow_recording", nullable = false)
-	private boolean allowRecording = true;
-
-	/**
-	 * @see Client#getZombieCheckFlag()
-	 */
-	@Column(name = "zombie_check_flag", nullable = false)
-	private boolean zombieCheckFlag = false;
-
-	/**
-	 * @see Client#getMicMuted()
-	 */
-	@Column(name = "mic_muted", nullable = false)
-	private boolean micMuted = false;
-
-	/**
-	 * @see Client#isSipTransport()
-	 */
-	@Column(name = "sip_transport", nullable = false)
-	private boolean sipTransport = false;
-
-	@Column(name = "mobile", nullable = false)
-	private boolean mobile = false;
-
-	@ManyToOne(fetch = FetchType.LAZY)
-	@JoinColumn(name = "server_id")
-	private Server server;
-
-	public Client() {}
-
-	public Client(String streamid, String publicSID, Long roomId,
-			Long userId, String firstname, String lastname,
-			String username, String connectedSince, String scope) {
-		super();
-		this.streamid = streamid;
-		this.publicSID = publicSID;
-		this.roomId = roomId;
-		this.userId = userId;
-		this.firstname = firstname;
-		this.lastname = lastname;
-		this.username = username;
-		this.connectedSince = CalendarPatterns.parseDateWithHour(connectedSince);
-		this.scope = scope;
-	}
-
-	public void setUserObject(Long userId, String username, String firstname, String lastname) {
-		this.userId = userId;
-		this.username = username;
-		this.firstname = firstname;
-		this.lastname = lastname;
-	}
-
-	public void setUserObject(String username, String firstname, String lastname) {
-		this.username = username;
-		this.firstname = firstname;
-		this.lastname = lastname;
-	}
-
-	@Override
-	public Long getId() {
-		return id;
-	}
-
-	@Override
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public Date getConnectedSince() {
-		return connectedSince;
-	}
-
-	public void setConnectedSince(Date connectedSince) {
-		this.connectedSince = connectedSince;
-	}
-
-	public boolean getIsMod() {
-		return isMod;
-	}
-
-	public void setIsMod(boolean isMod) {
-		this.isMod = isMod;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	public String getStreamid() {
-		return streamid;
-	}
-
-	public void setStreamid(String streamid) {
-		this.streamid = streamid;
-	}
-
-	public String getScope() {
-		return scope;
-	}
-
-	public void setScope(String scope) {
-		this.scope = scope;
-	}
-
-	public String getFormatedDate() {
-		return formatedDate;
-	}
-
-	public void setFormatedDate(String formatedDate) {
-		this.formatedDate = formatedDate;
-	}
-
-	public String getUsercolor() {
-		return usercolor;
-	}
-
-	public void setUsercolor(String usercolor) {
-		this.usercolor = usercolor;
-	}
-
-	public Integer getUserpos() {
-		return userpos;
-	}
-
-	public void setUserpos(Integer userpos) {
-		this.userpos = userpos;
-	}
-
-	public String getUserip() {
-		return userip;
-	}
-
-	public void setUserip(String userip) {
-		this.userip = userip;
-	}
-
-	public String getSwfurl() {
-		return swfurl;
-	}
-
-	public void setSwfurl(String swfurl) {
-		this.swfurl = swfurl;
-	}
-
-	public int getUserport() {
-		return userport;
-	}
-
-	public void setUserport(int userport) {
-		this.userport = userport;
-	}
-
-	public String getFirstname() {
-		return firstname;
-	}
-
-	public void setFirstname(String firstname) {
-		this.firstname = firstname;
-	}
-
-	public String getLanguage() {
-		return language;
-	}
-
-	public void setLanguage(String language) {
-		this.language = language;
-	}
-
-	public String getLastLogin() {
-		return lastLogin;
-	}
-
-	public void setLastLogin(String lastLogin) {
-		this.lastLogin = lastLogin;
-	}
-
-	public String getLastname() {
-		return lastname;
-	}
-
-	public void setLastname(String lastname) {
-		this.lastname = lastname;
-	}
-
-	public String getEmail() {
-		return email;
-	}
-
-	public void setEmail(String email) {
-		this.email = email;
-	}
-
-	public String getSecurityCode() {
-		return securityCode;
-	}
-
-	public void setSecurityCode(String securityCode) {
-		this.securityCode = securityCode;
-	}
-
-	public String getPicture_uri() {
-		return picture_uri;
-	}
-
-	public void setPicture_uri(String picture_uri) {
-		this.picture_uri = picture_uri;
-	}
-
-	public Long getUserId() {
-		return userId;
-	}
-
-	public void setUserId(Long userId) {
-		this.userId = userId;
-	}
-
-	public Long getRoomId() {
-		return roomId;
-	}
-
-	public void setRoomId(Long roomId) {
-		this.roomId = roomId;
-	}
-
-	public Date getRoomEnter() {
-		return roomEnter;
-	}
-
-	public void setRoomEnter(Date roomEnter) {
-		this.roomEnter = roomEnter;
-	}
-
-	public boolean getIsRecording() {
-		return isRecording;
-	}
-
-	public void setIsRecording(boolean isRecording) {
-		this.isRecording = isRecording;
-	}
-
-	public String getRoomRecordingName() {
-		return roomRecordingName;
-	}
-
-	public void setRoomRecordingName(String roomRecordingName) {
-		this.roomRecordingName = roomRecordingName;
-	}
-
-	public String getAvsettings() {
-		return avsettings;
-	}
-
-	public void setAvsettings(String avsettings) {
-		this.avsettings = avsettings;
-	}
-
-	public long getBroadCastID() {
-		return broadCastID;
-	}
-
-	public void setBroadCastID(long broadCastID) {
-		this.broadCastID = broadCastID;
-	}
-
-	public String getPublicSID() {
-		return publicSID;
-	}
-
-	public void setPublicSID(String publicSID) {
-		this.publicSID = publicSID;
-	}
-
-	public boolean getZombieCheckFlag() {
-		return zombieCheckFlag;
-	}
-
-	public void setZombieCheckFlag(boolean zombieCheckFlag) {
-		this.zombieCheckFlag = zombieCheckFlag;
-	}
-
-	public boolean getMicMuted() {
-		return micMuted;
-	}
-
-	public void setMicMuted(boolean micMuted) {
-		this.micMuted = micMuted;
-	}
-
-	public boolean getCanDraw() {
-		return canDraw;
-	}
-
-	public void setCanDraw(boolean canDraw) {
-		this.canDraw = canDraw;
-	}
-
-	public boolean getIsBroadcasting() {
-		return isBroadcasting;
-	}
-
-	public void setIsBroadcasting(boolean isBroadcasting) {
-		this.isBroadcasting = isBroadcasting;
-	}
-
-	public boolean getCanShare() {
-		return canShare;
-	}
-
-	public void setCanShare(boolean canShare) {
-		this.canShare = canShare;
-	}
-
-	public String getExternalUserId() {
-		return externalUserId;
-	}
-
-	public void setExternalUserId(String externalUserId) {
-		this.externalUserId = externalUserId;
-	}
-
-	public String getExternalUserType() {
-		return externalUserType;
-	}
-
-	public void setExternalUserType(String externalUserType) {
-		this.externalUserType = externalUserType;
-	}
-
-	public boolean getIsSuperModerator() {
-		return isSuperModerator;
-	}
-
-	public void setIsSuperModerator(boolean isSuperModerator) {
-		this.isSuperModerator = isSuperModerator;
-	}
-
-	public boolean isScreenClient() {
-		return screenClient;
-	}
-
-	public void setScreenClient(boolean screenClient) {
-		this.screenClient = screenClient;
-	}
-
-	public int getVWidth() {
-		return vWidth;
-	}
-
-	public void setVWidth(int width) {
-		vWidth = width;
-	}
-
-	public int getVHeight() {
-		return vHeight;
-	}
-
-	public void setVHeight(int height) {
-		vHeight = height;
-	}
-
-	public int getVX() {
-		return vX;
-	}
-
-	public void setVX(int vx) {
-		vX = vx;
-	}
-
-	public int getVY() {
-		return vY;
-	}
-
-	public void setVY(int vy) {
-		vY = vy;
-	}
-
-	public String getStreamPublishName() {
-		return streamPublishName;
-	}
-
-	public void setStreamPublishName(String streamPublishName) {
-		this.streamPublishName = streamPublishName;
-	}
-
-	public Long getRecordingId() {
-		return recordingId;
-	}
-
-	public void setRecordingId(Long recordingId) {
-		this.recordingId = recordingId;
-	}
-
-	public Long getRecordingMetaDataId() {
-		return recordingMetaDataId;
-	}
-
-	public void setRecordingMetaDataId(Long recordingMetaDataId) {
-		this.recordingMetaDataId = recordingMetaDataId;
-	}
-
-	public boolean isScreenPublishStarted() {
-		return screenPublishStarted;
-	}
-
-	public void setScreenPublishStarted(boolean screenPublishStarted) {
-		this.screenPublishStarted = screenPublishStarted;
-	}
-
-	public boolean isStartRecording() {
-		return startRecording;
-	}
-
-	public void setStartRecording(boolean startRecording) {
-		this.startRecording = startRecording;
-	}
-
-	public boolean isStartStreaming() {
-		return startStreaming;
-	}
-
-	public void setStartStreaming(boolean startStreaming) {
-		this.startStreaming = startStreaming;
-	}
-
-	public Integer getInterviewPodId() {
-		return interviewPodId;
-	}
-
-	public void setInterviewPodId(Integer interviewPodId) {
-		this.interviewPodId = interviewPodId;
-	}
-
-	public boolean getCanRemote() {
-		return canRemote;
-	}
-
-	public void setCanRemote(boolean canRemote) {
-		this.canRemote = canRemote;
-	}
-
-	public boolean getCanGiveAudio() {
-		return canGiveAudio;
-	}
-
-	public void setCanGiveAudio(boolean canGiveAudio) {
-		this.canGiveAudio = canGiveAudio;
-	}
-
-	public boolean getCanVideo() {
-		return canVideo;
-	}
-
-	public void setCanVideo(boolean canVideo) {
-		this.canVideo = canVideo;
-	}
-
-	public boolean isAllowRecording() {
-		return allowRecording;
-	}
-
-	public void setAllowRecording(boolean allowRecording) {
-		this.allowRecording = allowRecording;
-	}
-
-	public boolean isStreamPublishStarted() {
-		return streamPublishStarted;
-	}
-
-	public void setStreamPublishStarted(boolean streamPublishStarted) {
-		this.streamPublishStarted = streamPublishStarted;
-	}
-
-	public boolean isSipTransport() {
-		return sipTransport;
-	}
-
-	public void setSipTransport(boolean sipTransport) {
-		this.sipTransport = sipTransport;
-	}
-
-	public Server getServer() {
-		return server;
-	}
-
-	public void setServer(Server server) {
-		this.server = server;
-	}
-
-	public boolean isMobile() {
-		return mobile;
-	}
-
-	public void setMobile(boolean mobile) {
-		this.mobile = mobile;
-	}
-
-	public String getTcUrl() {
-		return tcUrl;
-	}
-
-	public void setTcUrl(String tcUrl) {
-		this.tcUrl = tcUrl;
-	}
-
-	public boolean isNativeSsl() {
-		return nativeSsl;
-	}
-
-	public void setNativeSsl(boolean nativeSsl) {
-		this.nativeSsl = nativeSsl;
-	}
-
-	@Override
-	public String toString() {
-		return "Client [streamid=" + streamid + ", publicSID=" + publicSID + ", isScreenClient=" + screenClient
-				+ ", isMobile = " + mobile + ", roomId=" + roomId + ", broadCastID=" + broadCastID + ", userId="
-				+ userId + ", avsettings=" + avsettings + ", isRecording=" + isRecording + ", recordingId="
-				+ recordingId + ", recordingMetaDataId=" + recordingMetaDataId + ", screenPublishStarted="
-				+ screenPublishStarted + ", interviewPodId=" + interviewPodId + ", server=" + server + "]";
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java
index 36cfd33..3e095cf 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java
@@ -303,7 +303,7 @@ public class Room implements IDataProviderEntity {
 	private List<RoomGroup> roomGroups = new ArrayList<>();
 
 	@Transient
-	private List<Client> currentusers;
+	private List<StreamClient> currentusers;
 
 	public String getComment() {
 		return comment;
@@ -371,11 +371,11 @@ public class Room implements IDataProviderEntity {
 		this.ispublic = ispublic;
 	}
 
-	public List<Client> getCurrentusers() {
+	public List<StreamClient> getCurrentusers() {
 		return currentusers;
 	}
 
-	public void setCurrentusers(List<Client> currentusers) {
+	public void setCurrentusers(List<StreamClient> currentusers) {
 		this.currentusers = currentusers;
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
new file mode 100644
index 0000000..2dc1fae
--- /dev/null
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
@@ -0,0 +1,896 @@
+/*
+ * 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.db.entity.room;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.openmeetings.db.entity.basic.IClient;
+import org.apache.openmeetings.db.entity.server.Server;
+import org.apache.openmeetings.util.CalendarPatterns;
+
+/**
+ * Can be configured to be stored in memory or in database
+ *
+ * @author sebawagner
+ */
+@Entity
+@NamedQueries({
+	@NamedQuery(name = "deleteAll", query = "DELETE FROM Client"),
+	@NamedQuery(name = "deletedById", query = "DELETE FROM Client c WHERE c.id = :id"),
+	@NamedQuery(name = "deleteClientsByServer", query = "DELETE FROM Client c WHERE c.server = :server"),
+	@NamedQuery(name = "deletedByServerAndStreamId", query = "DELETE FROM Client c WHERE c.server = :server AND c.streamid LIKE :streamid"),
+	@NamedQuery(name = "countClients", query = "SELECT count(c.id) FROM Client c"),
+	@NamedQuery(name = "countClientsByServer", query = "SELECT count(c.id) FROM Client c WHERE c.server = :server"),
+	@NamedQuery(name = "countClientsByServerAndStreamId", query = "SELECT count(c.id) FROM Client c WHERE c.streamid LIKE :streamid AND c.server = :server"),
+	@NamedQuery(name = "getClientByServerAndStreamId", query = "SELECT c FROM Client c WHERE c.streamid LIKE :streamid AND c.server = :server"),
+	@NamedQuery(name = "getClientsByPublicSIDAndServer", query = "SELECT c FROM Client c WHERE c.publicSID LIKE :publicSID AND c.server = :server"),
+	@NamedQuery(name = "getClientsByPublicSID", query = "SELECT c FROM Client c WHERE c.publicSID LIKE :publicSID"),
+	@NamedQuery(name = "getClientsByServer", query = "SELECT c FROM Client c WHERE c.server = :server"),
+	@NamedQuery(name = "getClients", query = "SELECT c FROM Client c"),
+	@NamedQuery(name = "getClientsWithServer", query = "SELECT c FROM Client c LEFT JOIN FETCH c.server"),
+	@NamedQuery(name = "getClientsByUserId", query = "SELECT c FROM Client c WHERE c.server = :server AND c.userId = :userId"),
+	@NamedQuery(name = "getClientsByRoomId", query = "SELECT c FROM Client c WHERE c.roomId = :roomId"),
+	@NamedQuery(name = "getRoomsIdsByServer", query = "SELECT c.roomId FROM Client c WHERE c.server = :server GROUP BY c.roomId")
+})
+@Table(name = "client")
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class StreamClient implements IClient {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.IDENTITY)
+	@Column(name = "id")
+	private Long id;
+
+	/**
+	 * @see StreamClient#getUsername()
+	 */
+	@Column(name = "username")
+	private String username = "";
+
+	/**
+	 * @see StreamClient#getStreamid()
+	 */
+	@Column(name = "streamid")
+	private String streamid = "";
+
+	/**
+	 * @see StreamClient#getScope()
+	 */
+	@Column(name = "scope")
+	private String scope = "";
+
+	/**
+	 * @see StreamClient#getVWidth()
+	 */
+	@Column(name = "vwidth")
+	private int vWidth = 0;
+
+	/**
+	 * @see StreamClient#getVHeight()
+	 */
+	@Column(name = "vheight")
+	private int vHeight = 0;
+
+	/**
+	 * @see StreamClient#getVX()
+	 */
+	@Column(name = "vx")
+	private int vX = 0;
+
+	/**
+	 * @see StreamClient#getVY()
+	 */
+	@Column(name = "vy")
+	private int vY = 0;
+
+	/**
+	 * @see StreamClient#getStreamPublishName()
+	 */
+	@Column(name = "stream_publish_name")
+	private String streamPublishName = "";
+
+	/**
+	 * @see StreamClient#getPublicSID()
+	 */
+	@Column(name = "public_sid")
+	private String publicSID = "";
+
+	/**
+	 * @see StreamClient#getIsMod()
+	 */
+	@Column(name = "is_mod", nullable = false)
+	private boolean isMod = false;
+
+	/**
+	 * @see StreamClient#getIsSuperModerator()
+	 */
+	@Column(name = "is_supermoderator", nullable = false)
+	private boolean isSuperModerator = false;
+
+	/**
+	 * @see StreamClient#getCanDraw()
+	 */
+	@Column(name = "can_draw", nullable = false)
+	private boolean canDraw = false;
+
+	/**
+	 * @see StreamClient#getCanShare()
+	 */
+	@Column(name = "can_share", nullable = false)
+	private boolean canShare = false;
+
+	/**
+	 * @see StreamClient#getCanRemote()
+	 */
+	@Column(name = "can_remote", nullable = false)
+	private boolean canRemote = false;
+
+	/**
+	 * @see StreamClient#getCanGiveAudio()
+	 */
+	@Column(name = "can_giveaudio", nullable = false)
+	private boolean canGiveAudio = false;
+
+	@Column(name = "can_video", nullable = false)
+	private boolean canVideo = false;
+
+	/**
+	 * @see StreamClient#getConnectedSince()
+	 */
+	@Column(name = "connected_since")
+	private Date connectedSince;
+
+	/**
+	 * @see StreamClient#getFormatedDate()
+	 */
+	@Column(name = "formated_date")
+	private String formatedDate;
+
+	/**
+	 * @see StreamClient#isScreenClient()
+	 */
+	@Column(name = "is_screenclient", nullable = false)
+	private boolean screenClient;
+
+	/**
+	 * @see StreamClient#getUsercolor()
+	 */
+	@Column(name = "usercolor")
+	private String usercolor;
+
+	/**
+	 * @see StreamClient#getUserpos()
+	 */
+	@Column(name = "userpos")
+	private Integer userpos;
+
+	/**
+	 * @see StreamClient#getUserip()
+	 */
+	@Column(name = "userip")
+	private String userip;
+
+	/**
+	 * @see StreamClient#getUserport()
+	 */
+	@Column(name = "userport")
+	private int userport;
+
+	/**
+	 * @see StreamClient#getRoomId()
+	 */
+	@Column(name = "room_id")
+	private Long roomId;
+
+	/**
+	 * @see StreamClient#getRoomEnter()
+	 */
+	@Column(name = "room_enter")
+	private Date roomEnter = null;
+
+	/**
+	 * @see StreamClient#getBroadCastID()
+	 */
+	@Column(name = "broadcast_id")
+	private long broadCastID = -2;
+
+	/**
+	 * @see StreamClient#getUserId()
+	 */
+	@Column(name = "user_id")
+	private Long userId = null;
+
+	/**
+	 * @see StreamClient#getFirstname()
+	 */
+	@Column(name = "firstname")
+	private String firstname = "";
+
+	/**
+	 * @see StreamClient#getLastname()
+	 */
+	@Column(name = "lastname")
+	private String lastname = "";
+
+	/**
+	 * @see StreamClient#getMail()
+	 */
+	@Column(name = "email")
+	private String email;
+
+	/**
+	 * @see StreamClient#getLastLogin()
+	 */
+	@Column(name = "last_login")
+	private String lastLogin;
+
+	/**
+	 * @see StreamClient#getSecurityCode()
+	 */
+	@Column(name = "security_code")
+	private String securityCode;
+
+	/**
+	 * @see StreamClient#getPicture_uri()
+	 */
+	@Column(name = "picture_uri")
+	private String picture_uri;
+
+	/**
+	 * @see StreamClient#getLanguage()
+	 */
+	@Column(name = "language")
+	private String language = "";
+
+	/**
+	 * @see StreamClient#getAvsettings()
+	 */
+	@Column(name = "avsettings")
+	private String avsettings = "";
+
+	/**
+	 * @see StreamClient#getSwfurl()
+	 */
+	// FIXME: Move to {@link ClientSession}
+	@Column(name = "swfurl", length=2048)
+	private String swfurl;
+
+	@Column(name = "tcurl", length=2048)
+	private String tcUrl;
+
+	@Column(name = "nativeSsl", nullable = false)
+	private boolean nativeSsl = false;
+
+	/**
+	 * @see StreamClient#getIsRecording()
+	 */
+	@Column(name = "is_recording", nullable = false)
+	private boolean isRecording = false;
+
+	/**
+	 * @see StreamClient#getRoomRecordingName()
+	 */
+	@Column(name = "room_recording_name")
+	private String roomRecordingName;
+
+	/**
+	 * @see StreamClient#getRecordingId()
+	 */
+	@Column(name = "recording_id")
+	private Long recordingId;
+
+	/**
+	 * @see StreamClient#getRecordingMetaDataId()
+	 */
+	@Column(name = "recording_metadata_id")
+	private Long recordingMetaDataId;
+
+	/**
+	 * @see StreamClient#isStartRecording()
+	 */
+	@Column(name = "start_recording", nullable = false)
+	private boolean startRecording = false;
+
+	/**
+	 * @see StreamClient#isStartStreaming()
+	 */
+	@Column(name = "start_streaming", nullable = false)
+	private boolean startStreaming = false;
+
+	/**
+	 * @see StreamClient#isScreenPublishStarted()
+	 */
+	@Column(name = "screen_publish_started", nullable = false)
+	private boolean screenPublishStarted = false;
+
+	/**
+	 * @see StreamClient#isStreamPublishStarted()
+	 */
+	@Column(name = "stream_publish_started", nullable = false)
+	private boolean streamPublishStarted = false;
+
+	/**
+	 * @see StreamClient#getIsBroadcasting()
+	 */
+	@Column(name = "is_broadcasting", nullable = false)
+	private boolean isBroadcasting = false;
+
+	/**
+	 * @see StreamClient#getExternalUserId()
+	 */
+	@Column(name = "external_user_id")
+	private String externalUserId;
+
+	/**
+	 * @see StreamClient#getExternalUserType()
+	 */
+	@Column(name = "external_user_type")
+	private String externalUserType;
+
+	/**
+	 * @see StreamClient#getInterviewPodId()
+	 */
+	@Column(name = "interview_pod_id")
+	private Integer interviewPodId = null;
+
+	/**
+	 * @see StreamClient#isAllowRecording()
+	 */
+	@Column(name = "allow_recording", nullable = false)
+	private boolean allowRecording = true;
+
+	/**
+	 * @see StreamClient#getZombieCheckFlag()
+	 */
+	@Column(name = "zombie_check_flag", nullable = false)
+	private boolean zombieCheckFlag = false;
+
+	/**
+	 * @see StreamClient#getMicMuted()
+	 */
+	@Column(name = "mic_muted", nullable = false)
+	private boolean micMuted = false;
+
+	/**
+	 * @see StreamClient#isSipTransport()
+	 */
+	@Column(name = "sip_transport", nullable = false)
+	private boolean sipTransport = false;
+
+	@Column(name = "mobile", nullable = false)
+	private boolean mobile = false;
+
+	@ManyToOne(fetch = FetchType.LAZY)
+	@JoinColumn(name = "server_id")
+	private Server server;
+
+	public StreamClient() {}
+
+	public StreamClient(String streamid, String publicSID, Long roomId,
+			Long userId, String firstname, String lastname,
+			String username, String connectedSince, String scope) {
+		super();
+		this.streamid = streamid;
+		this.publicSID = publicSID;
+		this.roomId = roomId;
+		this.userId = userId;
+		this.firstname = firstname;
+		this.lastname = lastname;
+		this.username = username;
+		this.connectedSince = CalendarPatterns.parseDateWithHour(connectedSince);
+		this.scope = scope;
+	}
+
+	public void setUserObject(Long userId, String username, String firstname, String lastname) {
+		this.userId = userId;
+		this.username = username;
+		this.firstname = firstname;
+		this.lastname = lastname;
+	}
+
+	public void setUserObject(String username, String firstname, String lastname) {
+		this.username = username;
+		this.firstname = firstname;
+		this.lastname = lastname;
+	}
+
+	@Override
+	public Long getId() {
+		return id;
+	}
+
+	@Override
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public Date getConnectedSince() {
+		return connectedSince;
+	}
+
+	public void setConnectedSince(Date connectedSince) {
+		this.connectedSince = connectedSince;
+	}
+
+	public boolean getIsMod() {
+		return isMod;
+	}
+
+	public void setIsMod(boolean isMod) {
+		this.isMod = isMod;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public String getStreamid() {
+		return streamid;
+	}
+
+	public void setStreamid(String streamid) {
+		this.streamid = streamid;
+	}
+
+	public String getScope() {
+		return scope;
+	}
+
+	public void setScope(String scope) {
+		this.scope = scope;
+	}
+
+	public String getFormatedDate() {
+		return formatedDate;
+	}
+
+	public void setFormatedDate(String formatedDate) {
+		this.formatedDate = formatedDate;
+	}
+
+	public String getUsercolor() {
+		return usercolor;
+	}
+
+	public void setUsercolor(String usercolor) {
+		this.usercolor = usercolor;
+	}
+
+	public Integer getUserpos() {
+		return userpos;
+	}
+
+	public void setUserpos(Integer userpos) {
+		this.userpos = userpos;
+	}
+
+	public String getUserip() {
+		return userip;
+	}
+
+	public void setUserip(String userip) {
+		this.userip = userip;
+	}
+
+	public String getSwfurl() {
+		return swfurl;
+	}
+
+	public void setSwfurl(String swfurl) {
+		this.swfurl = swfurl;
+	}
+
+	public int getUserport() {
+		return userport;
+	}
+
+	public void setUserport(int userport) {
+		this.userport = userport;
+	}
+
+	public String getFirstname() {
+		return firstname;
+	}
+
+	public void setFirstname(String firstname) {
+		this.firstname = firstname;
+	}
+
+	public String getLanguage() {
+		return language;
+	}
+
+	public void setLanguage(String language) {
+		this.language = language;
+	}
+
+	public String getLastLogin() {
+		return lastLogin;
+	}
+
+	public void setLastLogin(String lastLogin) {
+		this.lastLogin = lastLogin;
+	}
+
+	public String getLastname() {
+		return lastname;
+	}
+
+	public void setLastname(String lastname) {
+		this.lastname = lastname;
+	}
+
+	public String getEmail() {
+		return email;
+	}
+
+	public void setEmail(String email) {
+		this.email = email;
+	}
+
+	public String getSecurityCode() {
+		return securityCode;
+	}
+
+	public void setSecurityCode(String securityCode) {
+		this.securityCode = securityCode;
+	}
+
+	public String getPicture_uri() {
+		return picture_uri;
+	}
+
+	public void setPicture_uri(String picture_uri) {
+		this.picture_uri = picture_uri;
+	}
+
+	public Long getUserId() {
+		return userId;
+	}
+
+	public void setUserId(Long userId) {
+		this.userId = userId;
+	}
+
+	public Long getRoomId() {
+		return roomId;
+	}
+
+	public void setRoomId(Long roomId) {
+		this.roomId = roomId;
+	}
+
+	public Date getRoomEnter() {
+		return roomEnter;
+	}
+
+	public void setRoomEnter(Date roomEnter) {
+		this.roomEnter = roomEnter;
+	}
+
+	public boolean getIsRecording() {
+		return isRecording;
+	}
+
+	public void setIsRecording(boolean isRecording) {
+		this.isRecording = isRecording;
+	}
+
+	public String getRoomRecordingName() {
+		return roomRecordingName;
+	}
+
+	public void setRoomRecordingName(String roomRecordingName) {
+		this.roomRecordingName = roomRecordingName;
+	}
+
+	public String getAvsettings() {
+		return avsettings;
+	}
+
+	public void setAvsettings(String avsettings) {
+		this.avsettings = avsettings;
+	}
+
+	public long getBroadCastID() {
+		return broadCastID;
+	}
+
+	public void setBroadCastID(long broadCastID) {
+		this.broadCastID = broadCastID;
+	}
+
+	public String getPublicSID() {
+		return publicSID;
+	}
+
+	public void setPublicSID(String publicSID) {
+		this.publicSID = publicSID;
+	}
+
+	public boolean getZombieCheckFlag() {
+		return zombieCheckFlag;
+	}
+
+	public void setZombieCheckFlag(boolean zombieCheckFlag) {
+		this.zombieCheckFlag = zombieCheckFlag;
+	}
+
+	public boolean getMicMuted() {
+		return micMuted;
+	}
+
+	public void setMicMuted(boolean micMuted) {
+		this.micMuted = micMuted;
+	}
+
+	public boolean getCanDraw() {
+		return canDraw;
+	}
+
+	public void setCanDraw(boolean canDraw) {
+		this.canDraw = canDraw;
+	}
+
+	public boolean getIsBroadcasting() {
+		return isBroadcasting;
+	}
+
+	public void setIsBroadcasting(boolean isBroadcasting) {
+		this.isBroadcasting = isBroadcasting;
+	}
+
+	public boolean getCanShare() {
+		return canShare;
+	}
+
+	public void setCanShare(boolean canShare) {
+		this.canShare = canShare;
+	}
+
+	public String getExternalUserId() {
+		return externalUserId;
+	}
+
+	public void setExternalUserId(String externalUserId) {
+		this.externalUserId = externalUserId;
+	}
+
+	public String getExternalUserType() {
+		return externalUserType;
+	}
+
+	public void setExternalUserType(String externalUserType) {
+		this.externalUserType = externalUserType;
+	}
+
+	public boolean getIsSuperModerator() {
+		return isSuperModerator;
+	}
+
+	public void setIsSuperModerator(boolean isSuperModerator) {
+		this.isSuperModerator = isSuperModerator;
+	}
+
+	public boolean isScreenClient() {
+		return screenClient;
+	}
+
+	public void setScreenClient(boolean screenClient) {
+		this.screenClient = screenClient;
+	}
+
+	public int getVWidth() {
+		return vWidth;
+	}
+
+	public void setVWidth(int width) {
+		vWidth = width;
+	}
+
+	public int getVHeight() {
+		return vHeight;
+	}
+
+	public void setVHeight(int height) {
+		vHeight = height;
+	}
+
+	public int getVX() {
+		return vX;
+	}
+
+	public void setVX(int vx) {
+		vX = vx;
+	}
+
+	public int getVY() {
+		return vY;
+	}
+
+	public void setVY(int vy) {
+		vY = vy;
+	}
+
+	public String getStreamPublishName() {
+		return streamPublishName;
+	}
+
+	public void setStreamPublishName(String streamPublishName) {
+		this.streamPublishName = streamPublishName;
+	}
+
+	public Long getRecordingId() {
+		return recordingId;
+	}
+
+	public void setRecordingId(Long recordingId) {
+		this.recordingId = recordingId;
+	}
+
+	public Long getRecordingMetaDataId() {
+		return recordingMetaDataId;
+	}
+
+	public void setRecordingMetaDataId(Long recordingMetaDataId) {
+		this.recordingMetaDataId = recordingMetaDataId;
+	}
+
+	public boolean isScreenPublishStarted() {
+		return screenPublishStarted;
+	}
+
+	public void setScreenPublishStarted(boolean screenPublishStarted) {
+		this.screenPublishStarted = screenPublishStarted;
+	}
+
+	public boolean isStartRecording() {
+		return startRecording;
+	}
+
+	public void setStartRecording(boolean startRecording) {
+		this.startRecording = startRecording;
+	}
+
+	public boolean isStartStreaming() {
+		return startStreaming;
+	}
+
+	public void setStartStreaming(boolean startStreaming) {
+		this.startStreaming = startStreaming;
+	}
+
+	public Integer getInterviewPodId() {
+		return interviewPodId;
+	}
+
+	public void setInterviewPodId(Integer interviewPodId) {
+		this.interviewPodId = interviewPodId;
+	}
+
+	public boolean getCanRemote() {
+		return canRemote;
+	}
+
+	public void setCanRemote(boolean canRemote) {
+		this.canRemote = canRemote;
+	}
+
+	public boolean getCanGiveAudio() {
+		return canGiveAudio;
+	}
+
+	public void setCanGiveAudio(boolean canGiveAudio) {
+		this.canGiveAudio = canGiveAudio;
+	}
+
+	public boolean getCanVideo() {
+		return canVideo;
+	}
+
+	public void setCanVideo(boolean canVideo) {
+		this.canVideo = canVideo;
+	}
+
+	public boolean isAllowRecording() {
+		return allowRecording;
+	}
+
+	public void setAllowRecording(boolean allowRecording) {
+		this.allowRecording = allowRecording;
+	}
+
+	public boolean isStreamPublishStarted() {
+		return streamPublishStarted;
+	}
+
+	public void setStreamPublishStarted(boolean streamPublishStarted) {
+		this.streamPublishStarted = streamPublishStarted;
+	}
+
+	public boolean isSipTransport() {
+		return sipTransport;
+	}
+
+	public void setSipTransport(boolean sipTransport) {
+		this.sipTransport = sipTransport;
+	}
+
+	public Server getServer() {
+		return server;
+	}
+
+	public void setServer(Server server) {
+		this.server = server;
+	}
+
+	public boolean isMobile() {
+		return mobile;
+	}
+
+	public void setMobile(boolean mobile) {
+		this.mobile = mobile;
+	}
+
+	public String getTcUrl() {
+		return tcUrl;
+	}
+
+	public void setTcUrl(String tcUrl) {
+		this.tcUrl = tcUrl;
+	}
+
+	public boolean isNativeSsl() {
+		return nativeSsl;
+	}
+
+	public void setNativeSsl(boolean nativeSsl) {
+		this.nativeSsl = nativeSsl;
+	}
+
+	@Override
+	public String toString() {
+		return "Client [streamid=" + streamid + ", publicSID=" + publicSID + ", isScreenClient=" + screenClient
+				+ ", isMobile = " + mobile + ", roomId=" + roomId + ", broadCastID=" + broadCastID + ", userId="
+				+ userId + ", avsettings=" + avsettings + ", isRecording=" + isRecording + ", recordingId="
+				+ recordingId + ", recordingMetaDataId=" + recordingMetaDataId + ", screenPublishStarted="
+				+ screenPublishStarted + ", interviewPodId=" + interviewPodId + ", server=" + server + "]";
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
index 37f8d92..0eeea98 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
@@ -52,7 +52,7 @@ import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dao.user.IUserManager;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.dto.basic.SearchResult;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.Address;
 import org.apache.openmeetings.db.entity.user.GroupUser;
@@ -420,7 +420,7 @@ public class UserManager implements IUserManager {
 
 				sessionDao.clearSessionByRoomId(room_id);
 
-				for (Client rcl : sessionManager.getClientListByRoom(room_id)) {
+				for (StreamClient rcl : sessionManager.getClientListByRoom(room_id)) {
 					if (rcl == null) {
 						return true;
 					}
@@ -449,7 +449,7 @@ public class UserManager implements IUserManager {
 			Sessiondata sd = sessionDao.check(sid);
 			// admins only
 			if (AuthLevelUtil.hasWebServiceLevel(userDao.getRights(sd.getUserId()))) {
-				Client rcl = sessionManager.getClientByPublicSID(publicSID, null);
+				StreamClient rcl = sessionManager.getClientByPublicSID(publicSID, null);
 
 				if (rcl == null) {
 					return true;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
index b213480..0d8e37d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
@@ -30,7 +30,7 @@ import java.util.List;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.user.IUserService;
 import org.apache.openmeetings.db.entity.basic.IClient;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.web.admin.AdminPanel;
 import org.apache.openmeetings.web.admin.SearchableDataView;
 import org.apache.openmeetings.web.app.Application;
@@ -89,8 +89,8 @@ public class ConnectionsPanel extends AdminPanel {
 					@Override
 					protected void onSubmit(AjaxRequestTarget target) {
 						IClient _c = item.getModelObject();
-						if (_c instanceof Client) {
-							Client c = (Client)_c;
+						if (_c instanceof StreamClient) {
+							StreamClient c = (StreamClient)_c;
 							getBean(IUserService.class).kickUserByStreamId(getSid(), c.getStreamid()
 									, c.getServer() == null ? 0 : c.getServer().getId());
 						} else {
@@ -100,8 +100,8 @@ public class ConnectionsPanel extends AdminPanel {
 						target.add(container, details.setVisible(false));
 					}
 				};
-				if (_c instanceof Client) {
-					Client c = (Client)_c;
+				if (_c instanceof StreamClient) {
+					StreamClient c = (StreamClient)_c;
 					item.add(new Label("streamid"));
 					item.add(new Label("login", c.getUsername()));
 					item.add(new Label("since", c.getConnectedSince()));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
index aa234b5..1d7d12a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
@@ -34,7 +34,7 @@ import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dao.user.IUserService;
 import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.room.RoomGroup;
@@ -82,12 +82,12 @@ public class RoomForm extends AdminBaseForm<Room> {
 	private final TextField<String> pin = new TextField<>("pin");
 	private final WebMarkupContainer moderatorContainer = new WebMarkupContainer("moderatorContainer");
 	private final WebMarkupContainer clientsContainer = new WebMarkupContainer("clientsContainer");
-	private final ListView<Client> clients = new ListView<Client>("clients", new ArrayList<>()) {
+	private final ListView<StreamClient> clients = new ListView<StreamClient>("clients", new ArrayList<>()) {
 		private static final long serialVersionUID = 1L;
 
 		@Override
-		protected void populateItem(final ListItem<Client> item) {
-			Client client = item.getModelObject();
+		protected void populateItem(final ListItem<StreamClient> item) {
+			StreamClient client = item.getModelObject();
 			item.add(new Label("clientId", "" + client.getId()))
 				.add(new Label("clientLogin", "" + client.getUsername()))
 				.add(new ConfirmableAjaxBorder("clientDelete", getString("80"), getString("833")) {
@@ -95,7 +95,7 @@ public class RoomForm extends AdminBaseForm<Room> {
 
 					@Override
 					protected void onSubmit(AjaxRequestTarget target) {
-						Client c = item.getModelObject();
+						StreamClient c = item.getModelObject();
 						getBean(IUserService.class).kickUserByStreamId(getSid(), c.getStreamid()
 								, c.getServer() == null ? 0 : c.getServer().getId());
 
@@ -329,7 +329,7 @@ public class RoomForm extends AdminBaseForm<Room> {
 
 	void updateClients(AjaxRequestTarget target) {
 		long roomId = (getModelObject().getId() != null ? getModelObject().getId() : 0);
-		final List<Client> clientsInRoom = getBean(ISessionManager.class).getClientListByRoom(roomId);
+		final List<StreamClient> clientsInRoom = getBean(ISessionManager.class).getClientListByRoom(roomId);
 		clients.setDefaultModelObject(clientsInRoom);
 		target.add(clientsContainer);
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index ac7cfa8..2718c5f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -56,6 +56,7 @@ import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.util.InitializationContainer;
@@ -257,7 +258,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 		}
 	}
 
-	private static boolean hasVideo(org.apache.openmeetings.db.entity.room.Client rcl) {
+	private static boolean hasVideo(StreamClient rcl) {
 		return rcl != null && rcl.getAvsettings().contains("v");
 	}
 
@@ -266,7 +267,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	}
 
 	@Override
-	public org.apache.openmeetings.db.entity.room.Client updateClient(org.apache.openmeetings.db.entity.room.Client rcl, boolean forceSize) {
+	public StreamClient updateClient(StreamClient rcl, boolean forceSize) {
 		if (rcl == null) {
 			return null;
 		}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
index 17a0a57..d9e203e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
@@ -24,7 +24,7 @@ import static org.apache.openmeetings.web.app.Application.getBean;
 import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.session.SessionManager;
 import org.apache.openmeetings.db.dto.server.ClientSessionInfo;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.web.app.Application;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -32,13 +32,13 @@ import org.slf4j.Logger;
 public class RoomBroadcaster {
 	private static final Logger log = Red5LoggerFactory.getLogger(RoomBroadcaster.class, webAppRootKey);
 
-	public static Client getClient(String publicSid) {
+	public static StreamClient getClient(String publicSid) {
 		ClientSessionInfo csi = getBean(SessionManager.class).getClientByPublicSIDAnyServer(publicSid);
 		return csi == null ? null : csi.getRcl();
 	}
 
 	public static void broadcast(String publicSid, String method, Object obj) {
-		Client rc = getClient(publicSid);
+		StreamClient rc = getClient(publicSid);
 		if (rc == null) {
 			return;
 		}
@@ -51,7 +51,7 @@ public class RoomBroadcaster {
 	}
 
 	public static void sendUpdatedClient(org.apache.openmeetings.db.entity.basic.Client client) {
-		org.apache.openmeetings.db.entity.room.Client rcl = Application.get().updateClient(getClient(client.getUid()), true);
+		StreamClient rcl = Application.get().updateClient(getClient(client.getUid()), true);
 		log.debug("-----------  sendUpdatedClient ");
 
 		if (rcl == null) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 0cf02f3..6341021 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -34,10 +34,11 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.UUID;
 
-import org.apache.directory.api.util.Strings;
+import org.apache.openmeetings.core.util.RoomHelper;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
 import org.apache.openmeetings.db.dao.log.ConferenceLogDao;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
@@ -78,6 +79,7 @@ import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
@@ -122,7 +124,7 @@ public class RoomPanel extends BasePanel {
 			target.appendJavaScript(String.format("VideoManager.init(%s);", options));
 			WebSocketHelper.sendRoom(new RoomMessage(r.getId(), getUserId(), RoomMessage.Type.roomEnter));
 			// play video from other participants
-			playVideos(target);
+			initVideos(target);
 			getMainPanel().getChat().roomEnter(r, target);
 			if (r.isFilesOpened()) {
 				sidebar.setFilesActive(target);
@@ -157,14 +159,21 @@ public class RoomPanel extends BasePanel {
 		//private String publishingUser = null;
 	}
 
-	private void playVideos(AjaxRequestTarget target) {
-		for (Client c: getRoomClients(getRoom().getId()) ){
+	private void initVideos(AjaxRequestTarget target) {
+		StringBuilder sb = new StringBuilder();
+		for (Client c: getRoomClients(getRoom().getId()) ) {
 			boolean self = getClient().getUid().equals(c.getUid());
-			if (!self) {
-				JSONObject json = c.toJson(self).put("sid", getSid());
-				// TODO we should check if client is screenShare, see onEvent newStream case.
-				target.appendJavaScript(String.format("VideoManager.play(%s);", json));
+			if (c.hasAnyActivity(Client.Activity.broadcastA, Client.Activity.broadcastV)) {
+				sb.append(String.format("VideoManager.play(%s);"
+						, RoomHelper.videoJson(c, self, getSid(), getBean(ISessionManager.class), false)));
 			}
+			if (c.hasActivity(Client.Activity.share)) {
+				sb.append(String.format("VideoManager.play(%s);"
+						, RoomHelper.videoJson(c, self, getSid(), getBean(ISessionManager.class), true)));
+			}
+		}
+		if (!Strings.isEmpty(sb)) {
+			target.appendJavaScript(sb);
 		}
 	}
 
@@ -399,15 +408,8 @@ public class RoomPanel extends BasePanel {
 						Client c = getOnlineClient(obj.getString("uid"));
 						boolean self = getClient().getUid().equals(c.getUid());
 						if (!self) {
-							JSONObject json = c.toJson(self).put("sid", getSid());
-							if (obj.optBoolean("screenShare", false)) {
-								json.put("screenShare", true)
-									.put("uid", obj.getString("suid")) // unique screen-sharing ID
-									.put("broadcastId", obj.getString("broadcastId"))
-									.put("width", obj.getInt("width"))
-									.put("height", obj.getInt("height"));
-							}
-							handler.appendJavaScript(String.format("VideoManager.play(%s);", json));
+							handler.appendJavaScript(String.format("VideoManager.play(%s);"
+									, RoomHelper.videoJson(c, self, getSid(), getBean(ISessionManager.class), obj.optBoolean("screenShare", false))));
 						}
 					}
 						break;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
index 37d7115..bdb1ea8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
@@ -38,6 +38,7 @@ import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.room.RoomPoll;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.user.Group;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.message.RoomMessage.Type;
@@ -300,13 +301,13 @@ public class RoomMenuPanel extends Panel {
 		StringBuilder roomTitle = new StringBuilder();
 		if (room.getRecordingUser() != null) {
 			ISessionManager sessMngr = getBean(ISessionManager.class);
-			org.apache.openmeetings.db.entity.room.Client recUser = sessMngr.getClientByPublicSID(room.getRecordingUser(), null); //TODO check server
+			StreamClient recUser = sessMngr.getClientByPublicSID(room.getRecordingUser(), null); //TODO check server
 			if (recUser != null) {
 				roomTitle.append(String.format("%s %s %s %s %s", getString("419")
 						, recUser.getUsername(), recUser.getFirstname(), recUser.getLastname(), df.format(recUser.getConnectedSince())));
 				roomClass.append(" screen");
 			}
-			org.apache.openmeetings.db.entity.room.Client pubUser = sessMngr.getClientByPublicSID(room.getPublishingUser(), null); //TODO check server
+			StreamClient pubUser = sessMngr.getClientByPublicSID(room.getPublishingUser(), null); //TODO check server
 			if (pubUser != null) {
 				if (recUser != null) {
 					roomTitle.append('\n');

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index 1b2d687..f9e1087 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -31,7 +31,7 @@ var Video = (function() {
 		vc.width(w).height(h);
 		swf.attr('width', w).attr('height', h);
 	}
-	function _init(_box, _c) {
+	function _init(_box, _uid, _c) {
 		c = _c;
 		box = _box;
 		size = {width: c.width, height: c.height};
@@ -95,12 +95,13 @@ var Video = (function() {
 			o.cam = c.cam;
 			o.mic = c.mic;
 			o.mode = 'broadcast';
+			o.uid = c.uid;
 		} else {
 			o.mode = 'play';
+			o.uid = _uid;
 		}
 		o.width = c.width;
 		o.height = c.height;
-		o.uid = c.uid;
 		o.sid = c.sid;
 		o.broadcastId = c.broadcastId;
 		swf = initVideo(vc, _id + '-swf', o);
@@ -134,7 +135,7 @@ var VideoManager = (function() {
 			, av = audio || video
 			, v = $('#' + _id);
 		if (av && v.length != 1 && !!c.self) {
-			Video().init(box, c);
+			Video().init(box, options.uid, c);
 		} else if (av && v.length == 1) {
 			v.data().update(c);
 		} else if (!av && v.length == 1) {
@@ -142,7 +143,7 @@ var VideoManager = (function() {
 		}
 	}
 	function _play(c) {
-		Video().init(box, c);
+		Video().init(box, options.uid, c);
 	}
 	function _close(uid) {
 		var _id = _getVid(uid), v = $('#' + _id);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
index 388277e..6a138b9 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
@@ -46,7 +46,7 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
+		<class>org.apache.openmeetings.db.entity.room.StreamClient</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
index 1d2b86b..4304fe5 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
@@ -46,7 +46,7 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
+		<class>org.apache.openmeetings.db.entity.room.StreamClient</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
index e1124ba..46237d3 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
@@ -45,7 +45,7 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
+		<class>org.apache.openmeetings.db.entity.room.StreamClient</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.Whiteboard</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
index 5263a8e..798ec15 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
@@ -46,7 +46,7 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
+		<class>org.apache.openmeetings.db.entity.room.StreamClient</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
index 21367c0..2a62983 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
@@ -46,7 +46,7 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
+		<class>org.apache.openmeetings.db.entity.room.StreamClient</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
index baa331f..a93c70d 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
@@ -46,7 +46,7 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
+		<class>org.apache.openmeetings.db.entity.room.StreamClient</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java
index 720a7fc..6963911 100644
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java
+++ b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java
@@ -24,7 +24,7 @@ import java.util.List;
 
 import org.apache.openmeetings.db.dao.room.ClientDao;
 import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.test.AbstractJUnitDefaults;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
@@ -58,7 +58,7 @@ public class TestDbSession extends AbstractJUnitDefaults {
 			serverDao.update(server, null);
 		}
 
-		Client cl1 = new Client();
+		StreamClient cl1 = new StreamClient();
 		cl1.setStreamid("1");
 		cl1.setServer(null);
 		cl1.setUserId(1L);
@@ -66,7 +66,7 @@ public class TestDbSession extends AbstractJUnitDefaults {
 		cl1.setPublicSID("public1");
 		clientDao.add(cl1);
 
-		Client cl2 = new Client();
+		StreamClient cl2 = new StreamClient();
 		cl2.setStreamid("2");
 		cl2.setServer(null);
 		cl2.setRoomId(1L);
@@ -74,7 +74,7 @@ public class TestDbSession extends AbstractJUnitDefaults {
 		cl2.setPublicSID("public2");
 		clientDao.add(cl2);
 
-		Client cl3 = new Client();
+		StreamClient cl3 = new StreamClient();
 		cl3.setStreamid("3");
 		cl3.setServer(server);
 		cl3.setRoomId(3L);
@@ -82,21 +82,21 @@ public class TestDbSession extends AbstractJUnitDefaults {
 		cl3.setPublicSID("public3");
 		clientDao.add(cl3);
 		
-		Client clTest = clientDao.getClientByServerAndStreamId(null, "1");
+		StreamClient clTest = clientDao.getClientByServerAndStreamId(null, "1");
 
 		log.debug("cl1 " + cl1);
 		log.debug("clTest " + clTest);
 
 		assertEquals(clTest.getId(), cl1.getId());
 
-		Client clTest3 = clientDao.getClientByServerAndStreamId(server, "3");
+		StreamClient clTest3 = clientDao.getClientByServerAndStreamId(server, "3");
 
 		log.debug("cl3 " + cl3);
 		log.debug("clTest3 " + clTest3);
 
 		assertEquals(clTest3.getId(), cl3.getId());
 
-		Client clTest_NOT_3 = clientDao.getClientByServerAndStreamId(null, "3");
+		StreamClient clTest_NOT_3 = clientDao.getClientByServerAndStreamId(null, "3");
 
 		log.debug("clTest_NOT_3 " + clTest_NOT_3);
 		assertEquals(null, clTest_NOT_3);
@@ -110,51 +110,51 @@ public class TestDbSession extends AbstractJUnitDefaults {
 		long numberOfClients4 = clientDao.countClientsByServerAndStreamId(null, "3");
 		assertEquals(0, numberOfClients4);
 		
-		List<Client> clTest_Pub_1_list = clientDao.getClientsByPublicSIDAndServer(null, "public1");
+		List<StreamClient> clTest_Pub_1_list = clientDao.getClientsByPublicSIDAndServer(null, "public1");
 		assertEquals(cl1.getId(), clTest_Pub_1_list.get(0).getId());
 		
-		List<Client> clTest_Pub_3_list = clientDao.getClientsByPublicSIDAndServer(server, "public3");
+		List<StreamClient> clTest_Pub_3_list = clientDao.getClientsByPublicSIDAndServer(server, "public3");
 		assertEquals(cl3.getId(), clTest_Pub_3_list.get(0).getId());
 		
-		List<Client> clTest_Fail_list = clientDao.getClientsByPublicSIDAndServer(null, "public3");
+		List<StreamClient> clTest_Fail_list = clientDao.getClientsByPublicSIDAndServer(null, "public3");
 		assertEquals(0, clTest_Fail_list.size());
 		
-		List<Client> clTest_PubAll_1_list = clientDao.getClientsByPublicSID("public1");
+		List<StreamClient> clTest_PubAll_1_list = clientDao.getClientsByPublicSID("public1");
 		assertEquals(cl1.getId(), clTest_PubAll_1_list.get(0).getId());
 		
-		List<Client> clTest_PubAll_3_list = clientDao.getClientsByPublicSID("public3");
+		List<StreamClient> clTest_PubAll_3_list = clientDao.getClientsByPublicSID("public3");
 		assertEquals(cl3.getId(), clTest_PubAll_3_list.get(0).getId());
 		
-		List<Client> clTest_FailAll_list = clientDao.getClientsByPublicSID("public4");
+		List<StreamClient> clTest_FailAll_list = clientDao.getClientsByPublicSID("public4");
 		assertEquals(0, clTest_FailAll_list.size());
 		
-		List<Client> clientsByServerNull = clientDao.getClientsByServer(null);
+		List<StreamClient> clientsByServerNull = clientDao.getClientsByServer(null);
 		assertEquals(2, clientsByServerNull.size());
 		
-		List<Client> clientsByServer = clientDao.getClientsByServer(server);
+		List<StreamClient> clientsByServer = clientDao.getClientsByServer(server);
 		assertEquals(1, clientsByServer.size());
 		
-		List<Client> clientsAll = clientDao.getClients();
+		List<StreamClient> clientsAll = clientDao.getClients();
 		assertEquals(3, clientsAll.size());
 		
 		//by userid
-		List<Client> clTest_User_1_list = clientDao.getClientsByUserId(null, 1L);
+		List<StreamClient> clTest_User_1_list = clientDao.getClientsByUserId(null, 1L);
 		assertEquals(cl1.getId(), clTest_User_1_list.get(0).getId());
 		
-		List<Client> clTest_User_3_list = clientDao.getClientsByUserId(server, 3L);
+		List<StreamClient> clTest_User_3_list = clientDao.getClientsByUserId(server, 3L);
 		assertEquals(cl3.getId(), clTest_User_3_list.get(0).getId());
 		
-		List<Client> clTest_UserFail_list = clientDao.getClientsByUserId(null, 3L);
+		List<StreamClient> clTest_UserFail_list = clientDao.getClientsByUserId(null, 3L);
 		assertEquals(0, clTest_UserFail_list.size());
 		
 		//by roomid
-		List<Client> clTest_Room_1_list = clientDao.getClientsByRoomId(1L);
+		List<StreamClient> clTest_Room_1_list = clientDao.getClientsByRoomId(1L);
 		assertEquals(2, clTest_Room_1_list.size());
 		
-		List<Client> clTest_Room_3_list = clientDao.getClientsByRoomId(3L);
+		List<StreamClient> clTest_Room_3_list = clientDao.getClientsByRoomId(3L);
 		assertEquals(cl3.getId(), clTest_Room_3_list.get(0).getId());
 		
-		List<Client> clTest_RoomFail_list = clientDao.getClientsByRoomId(2L);
+		List<StreamClient> clTest_RoomFail_list = clientDao.getClientsByRoomId(2L);
 		assertEquals(0, clTest_RoomFail_list.size());
 		
 		//count all

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java
index 30a0ec1..946e15c 100644
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java
+++ b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java
@@ -24,7 +24,7 @@ import java.util.List;
 
 import org.apache.openmeetings.db.dao.room.ClientDao;
 import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.test.AbstractJUnitDefaults;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
@@ -58,7 +58,7 @@ public class TestDbSessionGetRoomIds extends AbstractJUnitDefaults {
 			serverDao.update(server, null);
 		}
 
-		Client cl1 = new Client();
+		StreamClient cl1 = new StreamClient();
 		cl1.setStreamid("1");
 		cl1.setServer(server);
 		cl1.setUserId(1L);
@@ -66,7 +66,7 @@ public class TestDbSessionGetRoomIds extends AbstractJUnitDefaults {
 		cl1.setPublicSID("public1");
 		clientDao.add(cl1);
 
-		Client cl2 = new Client();
+		StreamClient cl2 = new StreamClient();
 		cl2.setStreamid("2");
 		cl2.setServer(server);
 		cl2.setRoomId(1L);
@@ -74,7 +74,7 @@ public class TestDbSessionGetRoomIds extends AbstractJUnitDefaults {
 		cl2.setPublicSID("public2");
 		clientDao.add(cl2);
 
-		Client cl3 = new Client();
+		StreamClient cl3 = new StreamClient();
 		cl3.setStreamid("3");
 		cl3.setServer(server);
 		cl3.setRoomId(3L);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java
index e3dd291..4a50e47 100644
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java
+++ b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java
@@ -27,7 +27,7 @@ import java.util.Random;
 
 import org.apache.openmeetings.core.session.store.HashMapStore;
 import org.apache.openmeetings.core.session.store.IClientPersistenceStore;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.test.AbstractJUnitDefaults;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.crypt.CryptProvider;
@@ -54,7 +54,7 @@ public class TestHashMapSession extends AbstractJUnitDefaults {
 			
 			String streamId = ""+i;
 			
-			Client rcm = new Client();
+			StreamClient rcm = new StreamClient();
 			rcm.setConnectedSince(new Date());
 			rcm.setStreamid(streamId);
 			rcm.setScope("scopeName");


[40/50] [abbrv] openmeetings git commit: OPENMEETINGS-551 Minor changes: The video frames from other participants are shown when the new participant enter to the room.

Posted by so...@apache.org.
OPENMEETINGS-551 Minor changes: The video frames from other participants are shown when the new participant enter to the room.


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/1bd42d17
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/1bd42d17
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/1bd42d17

Branch: refs/heads/master
Commit: 1bd42d17f30c53583c42049c9ef1b4ff344403b4
Parents: 91866ad
Author: Vasiliy Degtyarev <vd...@apache.org>
Authored: Wed Apr 19 10:58:16 2017 +0000
Committer: Vasiliy Degtyarev <vd...@apache.org>
Committed: Wed Apr 19 10:58:16 2017 +0000

----------------------------------------------------------------------
 .../main/java/org/apache/openmeetings/web/room/RoomPanel.java  | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/1bd42d17/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 9990345..315acc0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -162,11 +162,7 @@ public class RoomPanel extends BasePanel {
 			boolean self = getClient().getUid().equals(c.getUid());
 			if (!self) {
 				JSONObject json = c.toJson().put("sid", getSid()).put("self", self);
-				json.put("screenShare", false)
-					.put("uid", c.getUid())
-					.put("broadcastId", c.getBroadcastId())
-					.put("width", c.getWidth())
-					.put("height", c.getHeight());
+				// TODO we should check if client is screenShare, see onEvent newStream case.
 				target.appendJavaScript(String.format("VideoManager.play(%s);", json));
 			}
 		}


[47/50] [abbrv] openmeetings git commit: [OPENMEETINGS-551] existing video streams are being played on room enter

Posted by so...@apache.org.
[OPENMEETINGS-551] existing video streams are being played on room enter


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/a260f5a8
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/a260f5a8
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/a260f5a8

Branch: refs/heads/master
Commit: a260f5a882b8f8c7fc28ee3ee07602f4c7f36f74
Parents: a600e32
Author: Maxim Solodovnik <so...@apache.org>
Authored: Sun Apr 23 04:23:36 2017 +0000
Committer: Maxim Solodovnik <so...@apache.org>
Committed: Sun Apr 23 04:23:36 2017 +0000

----------------------------------------------------------------------
 .../openmeetings/core/remote/MobileService.java |  22 +-
 .../core/remote/RecordingService.java           |  20 +-
 .../core/remote/ScopeApplicationAdapter.java    |  64 +-
 .../openmeetings/core/remote/UserService.java   |   8 +-
 .../core/session/SessionManager.java            |  68 +-
 .../core/session/store/DatabaseStore.java       |  32 +-
 .../core/session/store/HashMapStore.java        |  54 +-
 .../session/store/IClientPersistenceStore.java  |  22 +-
 .../openmeetings/core/util/RoomHelper.java      |  42 +
 .../org/apache/openmeetings/IApplication.java   |   4 +-
 .../openmeetings/db/dao/room/ClientDao.java     |  42 +-
 .../db/dao/server/ISessionManager.java          |  30 +-
 .../db/dao/server/SessiondataDao.java           |   4 +-
 .../openmeetings/db/dto/room/RoomStatus.java    |   8 +-
 .../db/dto/server/ClientSessionInfo.java        |  10 +-
 .../openmeetings/db/entity/basic/Client.java    |   5 +-
 .../openmeetings/db/entity/basic/IClient.java   |   2 +-
 .../openmeetings/db/entity/room/Client.java     | 896 -------------------
 .../openmeetings/db/entity/room/Room.java       |   6 +-
 .../db/entity/room/StreamClient.java            | 896 +++++++++++++++++++
 .../openmeetings/service/user/UserManager.java  |   6 +-
 .../web/admin/connection/ConnectionsPanel.java  |  10 +-
 .../openmeetings/web/admin/rooms/RoomForm.java  |  12 +-
 .../openmeetings/web/app/Application.java       |   5 +-
 .../openmeetings/web/room/RoomBroadcaster.java  |   8 +-
 .../apache/openmeetings/web/room/RoomPanel.java |  36 +-
 .../web/room/menu/RoomMenuPanel.java            |   5 +-
 .../org/apache/openmeetings/web/room/room.js    |   9 +-
 .../classes/META-INF/db2_persistence.xml        |   2 +-
 .../classes/META-INF/derby_persistence.xml      |   2 +-
 .../classes/META-INF/mssql_persistence.xml      |   2 +-
 .../classes/META-INF/mysql_persistence.xml      |   2 +-
 .../classes/META-INF/oracle_persistence.xml     |   2 +-
 .../classes/META-INF/postgresql_persistence.xml |   2 +-
 .../test/session/TestDbSession.java             |  44 +-
 .../test/session/TestDbSessionGetRoomIds.java   |   8 +-
 .../test/session/TestHashMapSession.java        |   4 +-
 37 files changed, 1217 insertions(+), 1177 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
index be56543..3e571c2 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
@@ -51,7 +51,7 @@ import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.IUserManager;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.ChatMessage;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.Group;
@@ -220,7 +220,7 @@ public class MobileService {
 		if (u != null) {
 			IConnection conn = Red5.getConnectionLocal();
 			String streamId = conn.getClient().getId();
-			Client c = sessionManager.getClientByStreamId(streamId, null);
+			StreamClient c = sessionManager.getClientByStreamId(streamId, null);
 			if (c == null) {
 				// Failed to create client
 				result.put("status", -1);
@@ -257,7 +257,7 @@ public class MobileService {
 		IConnection current = Red5.getConnectionLocal();
 		for (IConnection conn : current.getScope().getClientConnections()) {
 			if (conn != null && conn instanceof IServiceCapableConnection) {
-				Client c = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+				StreamClient c = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 				if (!Strings.isEmpty(c.getAvsettings()) && !c.isScreenClient()) {
 					Map<String, Object> map = new HashMap<>();
 					add(map, "streamId", c.getStreamid());
@@ -299,7 +299,7 @@ public class MobileService {
 		List<Map<String, Object>> result = new ArrayList<>();
 		// FIXME duplicated code
 		IConnection current = Red5.getConnectionLocal();
-		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+		StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		User u = userDao.get(c.getUserId());
 		//my rooms
 		List<Room> myl = new ArrayList<>();
@@ -336,7 +336,7 @@ public class MobileService {
 	public Map<String, Object> roomConnect(String SID, Long userId) {
 		// publicSid is changed on mobile room connect
 		IConnection current = Red5.getConnectionLocal();
-		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+		StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		Map<String, Object> result = new HashMap<>();
 		result.put("publicSid", c.getPublicSID());
 		result.put("broadCastId", c.getBroadCastID());
@@ -345,7 +345,7 @@ public class MobileService {
 
 	public Map<String, Object> updateAvMode(String avMode, String width, String height, Integer interviewPodId) {
 		IConnection current = Red5.getConnectionLocal();
-		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+		StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		c.setAvsettings(avMode);
 		if (!"n".equals(avMode)) {
 			c.setBroadCastID(nextBroadCastId());
@@ -371,7 +371,7 @@ public class MobileService {
 
 	public void sendChatMessage(String msg) {
 		IConnection current = Red5.getConnectionLocal();
-		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+		StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
 		ChatMessage m = new ChatMessage();
 		m.setMessage(msg);
@@ -391,7 +391,7 @@ public class MobileService {
 		sendChatMessage(sessionManager.getClientByPublicSID(uid, null), m, fmt);
 	}
 
-	public void sendChatMessage(Client c, ChatMessage m, FastDateFormat fmt) {
+	public void sendChatMessage(StreamClient c, ChatMessage m, FastDateFormat fmt) {
 		if (c == null) {
 			return;
 		}
@@ -404,14 +404,14 @@ public class MobileService {
 		new MessageSender(scopeAdapter.getRoomScope("" + roomId), "sendVarsToMessageWithClient", hsm, scopeAdapter) {
 			@Override
 			public boolean filter(IConnection conn) {
-				Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+				StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 				return rcl.isScreenClient()
 						|| rcl.getRoomId() == null || !rcl.getRoomId().equals(roomId);
 			}
 		}.start();
 	}
 
-	private static boolean isModerator(Client c) {
+	private static boolean isModerator(StreamClient c) {
 		return c.getIsMod() || c.getIsSuperModerator();
 	}
 
@@ -435,7 +435,7 @@ public class MobileService {
 		List<Map<String,Object>> myChatList = new ArrayList<>();
 		try {
 			IConnection current = Red5.getConnectionLocal();
-			Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+			StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 			Long roomId = c.getRoomId();
 
 			log.debug("GET CHATROOM: " + roomId);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
index 5e2fe7f..e0bcd21 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
@@ -39,7 +39,7 @@ import org.apache.openmeetings.db.entity.file.FileItem.Type;
 import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.record.RecordingMetaData;
 import org.apache.openmeetings.db.entity.record.RecordingMetaData.Status;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.CalendarPatterns;
 import org.apache.openmeetings.util.message.RoomMessage;
@@ -94,7 +94,7 @@ public class RecordingService implements IPendingServiceCallback {
 		return "rec_" + recordingId + "_stream_" + streamid + "_" + dateString;
 	}
 
-	public String recordMeetingStream(IConnection current, Client client, String roomRecordingName, String comment, boolean isInterview) {
+	public String recordMeetingStream(IConnection current, StreamClient client, String roomRecordingName, String comment, boolean isInterview) {
 		try {
 			log.debug("##REC:: recordMeetingStream ::");
 
@@ -140,7 +140,7 @@ public class RecordingService implements IPendingServiceCallback {
 			for (IConnection conn : current.getScope().getClientConnections()) {
 				if (conn != null) {
 					if (conn instanceof IServiceCapableConnection) {
-						Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+						StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 						// Send every user a notification that the recording did start
 						WebSocketHelper.sendRoom(new TextRoomMessage(roomId, ownerId, RoomMessage.Type.recordingStarted, client.getPublicSID()));
@@ -306,7 +306,7 @@ public class RecordingService implements IPendingServiceCallback {
 		}
 	}
 
-	public Long stopRecordAndSave(IScope scope, Client client, Long storedRecordingId) {
+	public Long stopRecordAndSave(IScope scope, StreamClient client, Long storedRecordingId) {
 		try {
 			log.debug("stopRecordAndSave " + client.getUsername() + "," + client.getUserip());
 			WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.recordingStoped, client.getPublicSID()));
@@ -315,7 +315,7 @@ public class RecordingService implements IPendingServiceCallback {
 			for (IConnection conn : scope.getClientConnections()) {
 				if (conn != null) {
 					if (conn instanceof IServiceCapableConnection) {
-						Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+						StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 						if (rcl == null) {
 							continue;
@@ -372,18 +372,18 @@ public class RecordingService implements IPendingServiceCallback {
 		return new Long(-1);
 	}
 
-	public Client checkLzRecording() {
+	public StreamClient checkLzRecording() {
 		try {
 			IConnection current = Red5.getConnectionLocal();
 			String streamid = current.getClient().getId();
 
 			log.debug("getCurrentRoomClient -2- " + streamid);
 
-			Client currentClient = sessionManager.getClientByStreamId(streamid, null);
+			StreamClient currentClient = sessionManager.getClientByStreamId(streamid, null);
 
 			log.debug("getCurrentRoomClient -#########################- " + currentClient.getRoomId());
 
-			for (Client rcl : sessionManager.getClientListByRoomAll(currentClient.getRoomId())) {
+			for (StreamClient rcl : sessionManager.getClientListByRoomAll(currentClient.getRoomId())) {
 				if (rcl.getIsRecording()) {
 					return rcl;
 				}
@@ -395,7 +395,7 @@ public class RecordingService implements IPendingServiceCallback {
 		return null;
 	}
 
-	public void stopRecordingShowForClient(IScope scope, Client rcl) {
+	public void stopRecordingShowForClient(IScope scope, StreamClient rcl) {
 		try {
 			// this cannot be handled here, as to stop a stream and to leave a
 			// room is not
@@ -433,7 +433,7 @@ public class RecordingService implements IPendingServiceCallback {
 		}
 	}
 
-	public void addRecordingByStreamId(IConnection conn, Client rcl, Long recordingId) {
+	public void addRecordingByStreamId(IConnection conn, StreamClient rcl, Long recordingId) {
 		try {
 			Recording recording = recordingDao.get(recordingId);
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
index 676737e..bfb251a 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
@@ -50,7 +50,7 @@ import org.apache.openmeetings.db.dao.server.ServerDao;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.log.ConferenceLog;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
@@ -196,7 +196,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		}
 		StringValue scn = StringValue.valueOf(conn.getScope().getName());
 		long roomId = scn.toLong(Long.MIN_VALUE);
-		Client rcm = new Client();
+		StreamClient rcm = new StreamClient();
 		IApplication iapp = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
 		if (!Strings.isEmpty(securityCode)) {
 			//this is for external applications like ffmpeg [OPENMEETINGS-1574]
@@ -215,7 +215,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 				log.warn("Client is not found by security id, client is rejected");
 				return rejectClient();
 			}
-			Client parent = sessionManager.getClientByPublicSID(_uid, null);
+			StreamClient parent = sessionManager.getClientByPublicSID(_uid, null);
 			if (parent == null || !parent.getScope().equals(scn.toString())) {
 				log.warn("Security code is invalid, client is rejected");
 				return rejectClient();
@@ -327,7 +327,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			log.debug("-----------  screenSharerAction ENTER");
 			IConnection current = Red5.getConnectionLocal();
 
-			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+			StreamClient client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
 			if (client != null) {
 				boolean changed = false;
@@ -384,7 +384,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			log.debug("-----------  setConnectionAsSharingClient");
 			IConnection current = Red5.getConnectionLocal();
 
-			Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+			StreamClient client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
 			if (client != null) {
 				boolean startRecording = Boolean.parseBoolean("" + map.get("startRecording"));
@@ -469,7 +469,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		try {
 			log.debug("[roomLeave] {} {} {} {}", client.getId(), room.getClients().size(), room.getContextPath(), room.getName());
 
-			Client rcl = sessionManager.getClientByStreamId(client.getId(), null);
+			StreamClient rcl = sessionManager.getClientByStreamId(client.getId(), null);
 
 			// The Room Client can be null if the Client left the room by using
 			// logicalRoomLeave
@@ -483,7 +483,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	}
 
 	public void roomLeaveByScope(String uid, Long roomId) {
-		Client rcl = sessionManager.getClientByPublicSID(uid, null);
+		StreamClient rcl = sessionManager.getClientByPublicSID(uid, null);
 		IScope scope = getRoomScope("" + roomId);
 		log.debug("[roomLeaveByScope] {} {} {} {}", uid, roomId, rcl, scope);
 		if (rcl != null && scope != null) {
@@ -501,7 +501,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	 * @param client
 	 * @param scope
 	 */
-	public void roomLeaveByScope(Client client, IScope scope) {
+	public void roomLeaveByScope(StreamClient client, IScope scope) {
 		try {
 			log.debug("[roomLeaveByScope] currentClient " + client);
 			if (client.isScreenClient() && client.isStartStreaming()) {
@@ -539,7 +539,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			new MessageSender(scope, "roomDisconnect", client, this) {
 				@Override
 				public boolean filter(IConnection conn) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+					StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 					if (rcl == null) {
 						return true;
 					}
@@ -576,11 +576,11 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			log.debug("-----------  streamPublishStart");
 			IConnection current = Red5.getConnectionLocal();
 			final String streamid = current.getClient().getId();
-			final Client c = sessionManager.getClientByStreamId(streamid, null);
+			final StreamClient c = sessionManager.getClientByStreamId(streamid, null);
 
 			//We make a second object the has the reference to the object
 			//that we will use to send to all participents
-			Client clientObjectSendToSync = c;
+			StreamClient clientObjectSendToSync = c;
 
 			// Notify all the clients that the stream had been started
 			log.debug("start streamPublishStart broadcast start: " + stream.getPublishedName() + " CONN " + current);
@@ -608,7 +608,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 			new MessageSender(current, "newStream", clientObjectSendToSync, this) {
 				@Override
 				public boolean filter(IConnection conn) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+					StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 					if (rcl == null) {
 						log.debug("RCL IS NULL newStream SEND");
@@ -638,15 +638,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 					return false;
 				}
 			}.start();
-			JSONObject obj = new JSONObject().put("uid", c.getPublicSID());
-			if (c.isScreenClient()) {
-				obj.put("screenShare", true)
-						.put("uid", c.getStreamPublishName())
-						.put("broadcastId", stream.getPublishedName())
-						.put("suid", c.getPublicSID())
-						.put("width", c.getVWidth())
-						.put("height", c.getVHeight());
-			}
+			JSONObject obj = new JSONObject().put("uid", c.getPublicSID()).put("screenShare", c.isScreenClient());
 			WebSocketHelper.sendRoom(new TextRoomMessage(c.getRoomId(), c.getUserId(), RoomMessage.Type.newStream, obj.toString()));
 		} catch (Exception err) {
 			log.error("[streamPublishStart]", err);
@@ -668,7 +660,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		try {
 			IConnection current = Red5.getConnectionLocal();
 			String streamId = current.getClient().getId();
-			Client rcl = sessionManager.getClientByStreamId(streamId, null);
+			StreamClient rcl = sessionManager.getClientByStreamId(streamId, null);
 
 			if (rcl == null) {
 
@@ -708,7 +700,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	public void setNewCursorPosition(Object item) {
 		try {
 			IConnection current = Red5.getConnectionLocal();
-			Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+			StreamClient c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
 			@SuppressWarnings("rawtypes")
 			Map cursor = (Map) item;
@@ -724,7 +716,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		try {
 			log.debug("-----------  switchMicMuted: " + publicSID);
 
-			Client currentClient = sessionManager.getClientByPublicSID(publicSID, null);
+			StreamClient currentClient = sessionManager.getClientByPublicSID(publicSID, null);
 			if (currentClient == null) {
 				return -1L;
 			}
@@ -791,7 +783,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		new MessageSender(getRoomScope("" + roomId), method, obj, this) {
 			@Override
 			public boolean filter(IConnection conn) {
-				Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+				StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 				return rcl == null || rcl.isScreenClient()
 						|| rcl.getRoomId() == null || !rcl.getRoomId().equals(roomId) || userDao.get(rcl.getUserId()) == null;
 			}
@@ -931,7 +923,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	public int sendMessageWithClientWithSyncObject(Object newMessage, boolean sync) {
 		try {
 			IConnection current = Red5.getConnectionLocal();
-			Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+			StreamClient currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
 			Map<String, Object> hsm = new HashMap<>();
 			hsm.put("client", currentClient);
@@ -989,7 +981,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	public int sendMessageWithClientById(Object newMessage, String clientId) {
 		try {
 			IConnection current = Red5.getConnectionLocal();
-			Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+			StreamClient currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
 			Map<String, Object> hsm = new HashMap<>();
 			hsm.put("client", currentClient);
@@ -1021,7 +1013,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 
 			for (IConnection conn : current.getScope().getClientConnections()) {
 				if (conn != null) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+					StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 					if (rcl.getIsRecording()) {
 						return true;
@@ -1046,14 +1038,14 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 
 			for (IConnection conn : current.getScope().getClientConnections()) {
 				if (conn != null) {
-					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+					StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 					if (rcl != null && rcl.getIsRecording()) {
 						return false;
 					}
 				}
 			}
-			Client current_rcl = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+			StreamClient current_rcl = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
 			// Also set the Recording Flag to Record all Participants that enter
 			// later
@@ -1102,7 +1094,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	private Long checkRecordingClient(IConnection conn) {
 		Long recordingId = null;
 		if (conn != null) {
-			Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
+			StreamClient rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 			if (rcl != null && rcl.getIsRecording()) {
 				rcl.setIsRecording(false);
 				recordingId = rcl.getRecordingId();
@@ -1123,7 +1115,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	 */
 	public boolean stopInterviewRecording() {
 		IConnection current = Red5.getConnectionLocal();
-		Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
+		StreamClient currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		return _stopInterviewRecording(currentClient, current.getScope());
 	}
 
@@ -1132,7 +1124,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 	 *
 	 * @return true if interview was found
 	 */
-	private boolean _stopInterviewRecording(Client currentClient, IScope currentScope) {
+	private boolean _stopInterviewRecording(StreamClient currentClient, IScope currentScope) {
 		try {
 			log.debug("-----------  stopInterviewRecording");
 			Long clientRecordingId = currentClient.getRecordingId();
@@ -1182,7 +1174,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		//verify
 		for (Iterator<Long> i = result.iterator(); i.hasNext();) {
 			Long id = i.next();
-			List<Client> rcs = sessionManager.getClientListByRoom(id);
+			List<StreamClient> rcs = sessionManager.getClientListByRoom(id);
 			if (rcs.size() == 0 || (rcs.size() == 1 && rcs.get(0).isSipTransport())) {
 				i.remove();
 			}
@@ -1220,7 +1212,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		log.debug("-----------  updateSipTransport");
 		IConnection current = Red5.getConnectionLocal();
 		String streamid = current.getClient().getId();
-		Client client = sessionManager.getClientByStreamId(streamid, null);
+		StreamClient client = sessionManager.getClientByStreamId(streamid, null);
 		Long roomId = client.getRoomId();
 		Integer count = getSipConferenceMembersNumber(roomId);
 		String newNumber = getSipTransportLastname(count);
@@ -1241,7 +1233,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
 		IClient c = current.getClient();
 		String streamid = c.getId();
 		// Notify all clients of the same scope (room)
-		Client currentClient = sessionManager.getClientByStreamId(streamid, null);
+		StreamClient currentClient = sessionManager.getClientByStreamId(streamid, null);
 		currentClient.setSipTransport(true);
 		currentClient.setRoomId(roomId);
 		currentClient.setRoomEnter(new Date());

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
index 7cc741a..6df8b37 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
@@ -31,7 +31,7 @@ import org.apache.openmeetings.db.dao.server.ServerDao;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.IUserService;
 import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.User;
@@ -130,7 +130,7 @@ public class UserService implements IUserService {
 			// admins only
 			if (AuthLevelUtil.hasAdminLevel(userDao.getRights(sd.getUserId()))) {
 				if (serverId == 0) {
-					Client rcl = sessionManager.getClientByStreamId(streamid, null);
+					StreamClient rcl = sessionManager.getClientByStreamId(streamid, null);
 
 					if (rcl == null) {
 						return true;
@@ -150,7 +150,7 @@ public class UserService implements IUserService {
 					return true;
 				} else {
 					Server server = serverDao.get(serverId);
-					Client rcl = sessionManager.getClientByStreamId(
+					StreamClient rcl = sessionManager.getClientByStreamId(
 							streamid, server);
 					slaveHTTPConnectionManager.kickSlaveUser(server, rcl.getPublicSID());
 
@@ -183,7 +183,7 @@ public class UserService implements IUserService {
 			Sessiondata sd = sessionDao.check(sid);
 			// users only
 			if (AuthLevelUtil.hasUserLevel(userDao.getRights(sd.getUserId()))) {
-				Client rcl = sessionManager.getClientByPublicSID(publicSID, null);
+				StreamClient rcl = sessionManager.getClientByPublicSID(publicSID, null);
 
 				if (rcl == null) {
 					return true;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
index cc3121f..84f2bf9 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
@@ -33,7 +33,7 @@ import org.apache.openmeetings.core.session.store.IClientPersistenceStore;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dto.basic.SearchResult;
 import org.apache.openmeetings.db.dto.server.ClientSessionInfo;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
@@ -41,7 +41,7 @@ import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
- * Handle {@link Client} objects.
+ * Handle {@link StreamClient} objects.
  *
  * Use a kind of decorator pattern to inject the {@link Server} into every call.
  *
@@ -75,7 +75,7 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public Client add(Client c, Server server) {
+	public StreamClient add(StreamClient c, Server server) {
 		if (c == null) {
 			return null;
 		}
@@ -99,7 +99,7 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public Client addClientListItem(String streamId, String scopeName,
+	public StreamClient addClientListItem(String streamId, String scopeName,
 			int remotePort, String remoteAddress, String swfUrl, Server server) {
 		if (server == null) {
 			server = serverUtil.getCurrentServer();
@@ -107,7 +107,7 @@ public class SessionManager implements ISessionManager {
 		try {
 
 			// Store the Connection into a bean and add it to the HashMap
-			Client rcm = new Client();
+			StreamClient rcm = new StreamClient();
 			rcm.setConnectedSince(new Date());
 			rcm.setStreamid(streamId);
 			rcm.setScope(scopeName);
@@ -134,17 +134,17 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public Collection<Client> getClients() {
+	public Collection<StreamClient> getClients() {
 		return cache.getClients();
 	}
 
 	@Override
-	public Collection<Client> getClientsWithServer() {
+	public Collection<StreamClient> getClientsWithServer() {
 		return cache.getClientsWithServer();
 	}
 
 	@Override
-	public Client getClientByStreamId(String streamId, Server server) {
+	public StreamClient getClientByStreamId(String streamId, Server server) {
 		if (server == null) {
 			server = serverUtil.getCurrentServer();
 		}
@@ -161,12 +161,12 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public Client getClientByPublicSID(String publicSID, Server server) {
+	public StreamClient getClientByPublicSID(String publicSID, Server server) {
 		if (server == null) {
 			server = serverUtil.getCurrentServer();
 		}
 		try {
-			List<Client> list = cache.getClientsByPublicSID(server, publicSID);
+			List<StreamClient> list = cache.getClientsByPublicSID(server, publicSID);
 			return list == null || list.isEmpty() ? null : list.get(0);
 		} catch (Exception err) {
 			log.error("[getClientByPublicSID]", err);
@@ -177,8 +177,8 @@ public class SessionManager implements ISessionManager {
 	@Override
 	public ClientSessionInfo getClientByPublicSIDAnyServer(String publicSID) {
 		try {
-			for (Entry<Long,List<Client>> entry : cache.getClientsByPublicSID(publicSID).entrySet()) {
-				for (Client rcl : entry.getValue()) {
+			for (Entry<Long,List<StreamClient>> entry : cache.getClientsByPublicSID(publicSID).entrySet()) {
+				for (StreamClient rcl : entry.getValue()) {
 					return new ClientSessionInfo(rcl, entry.getKey());
 				}
 			}
@@ -189,9 +189,9 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public Client getClientByUserId(Long userId) {
+	public StreamClient getClientByUserId(Long userId) {
 		try {
-			for (Client rcl : cache.getClientsByUserId(null, userId)) {
+			for (StreamClient rcl : cache.getClientsByUserId(null, userId)) {
 				if (rcl.isScreenClient()) {
 					continue;
 				}
@@ -205,13 +205,13 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public boolean updateAVClientByStreamId(String streamId, Client rcm, Server server) {
+	public boolean updateAVClientByStreamId(String streamId, StreamClient rcm, Server server) {
 		if (server == null) {
 			server = serverUtil.getCurrentServer();
 		}
 		try {
 			// get the corresponding user session object and update the settings
-			Client rclUsual = getClientByPublicSID(rcm.getPublicSID(), server);
+			StreamClient rclUsual = getClientByPublicSID(rcm.getPublicSID(), server);
 			if (rclUsual != null) {
 				rclUsual.setBroadCastID(rcm.getBroadCastID());
 				rclUsual.setAvsettings(rcm.getAvsettings());
@@ -219,7 +219,7 @@ public class SessionManager implements ISessionManager {
 				rclUsual.setVWidth(rcm.getVWidth());
 				rclUsual.setVX(rcm.getVX());
 				rclUsual.setVY(rcm.getVY());
-				Client rclSaved = cache.get(server, rclUsual.getStreamid());
+				StreamClient rclSaved = cache.get(server, rclUsual.getStreamid());
 				if (rclSaved != null) {
 					cache.put(rclUsual.getStreamid(), rclUsual);
 				} else {
@@ -236,12 +236,12 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public boolean updateClientByStreamId(String streamId, Client rcm, boolean updateRoomCount, Server server) {
+	public boolean updateClientByStreamId(String streamId, StreamClient rcm, boolean updateRoomCount, Server server) {
 		if (server == null) {
 			server = serverUtil.getCurrentServer();
 		}
 		try {
-			Client rclSaved = cache.get(server, streamId);
+			StreamClient rclSaved = cache.get(server, streamId);
 
 			if (rclSaved != null) {
 				cache.put(streamId, rcm);
@@ -274,10 +274,10 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public List<Client> getClientListByRoom(Long roomId) {
-		List<Client> roomClientList = new ArrayList<>();
+	public List<StreamClient> getClientListByRoom(Long roomId) {
+		List<StreamClient> roomClientList = new ArrayList<>();
 		try {
-			for (Client rcl : cache.getClientsByRoomId(roomId)) {
+			for (StreamClient rcl : cache.getClientsByRoomId(roomId)) {
 				if (rcl.isScreenClient()) {
 					continue;
 				}
@@ -294,7 +294,7 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public Collection<Client> getClientListByRoomAll(Long roomId) {
+	public Collection<StreamClient> getClientListByRoomAll(Long roomId) {
 		try {
 			return cache.getClientsByRoomId(roomId);
 		} catch (Exception err) {
@@ -304,10 +304,10 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public List<Client> getCurrentModeratorByRoom(Long roomId) {
-		List<Client> rclList = new LinkedList<>();
-		List<Client> currentClients = this.getClientListByRoom(roomId);
-		for (Client rcl : currentClients) {
+	public List<StreamClient> getCurrentModeratorByRoom(Long roomId) {
+		List<StreamClient> rclList = new LinkedList<>();
+		List<StreamClient> currentClients = this.getClientListByRoom(roomId);
+		for (StreamClient rcl : currentClients) {
 			if (rcl.getIsMod()) {
 				rclList.add(rcl);
 			}
@@ -316,9 +316,9 @@ public class SessionManager implements ISessionManager {
 	}
 
 	@Override
-	public SearchResult<Client> getListByStartAndMax(int start, int max, String orderby, boolean asc) {
-		SearchResult<Client> sResult = new SearchResult<>();
-		sResult.setObjectName(Client.class.getName());
+	public SearchResult<StreamClient> getListByStartAndMax(int start, int max, String orderby, boolean asc) {
+		SearchResult<StreamClient> sResult = new SearchResult<>();
+		sResult.setObjectName(StreamClient.class.getName());
 		sResult.setRecords(Long.valueOf(cache.size()));
 		sResult.setResult(cache.getClientsWithServer());
 		return sResult;
@@ -326,9 +326,9 @@ public class SessionManager implements ISessionManager {
 
 	@Override
 	public long getRecordingCount(long roomId) {
-		List<Client> currentClients = this.getClientListByRoom(roomId);
+		List<StreamClient> currentClients = this.getClientListByRoom(roomId);
 		int numberOfRecordingUsers = 0;
-		for (Client rcl : currentClients) {
+		for (StreamClient rcl : currentClients) {
 			if (rcl.isStartRecording()) {
 				numberOfRecordingUsers++;
 			}
@@ -338,9 +338,9 @@ public class SessionManager implements ISessionManager {
 
 	@Override
 	public long getPublishingCount(long roomId) {
-		List<Client> currentClients = this.getClientListByRoom(roomId);
+		List<StreamClient> currentClients = this.getClientListByRoom(roomId);
 		int numberOfPublishingUsers = 0;
-		for (Client rcl : currentClients) {
+		for (StreamClient rcl : currentClients) {
 			if (rcl.isStreamPublishStarted()) {
 				numberOfPublishingUsers++;
 			}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/DatabaseStore.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/DatabaseStore.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/DatabaseStore.java
index 5e79da3..84ce5b2 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/DatabaseStore.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/DatabaseStore.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.openmeetings.db.dao.room.ClientDao;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -40,7 +40,7 @@ public class DatabaseStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public void put(String streamId, Client rcl) {
+	public void put(String streamId, StreamClient rcl) {
 		if (rcl.getId() != null) {
 			clientDao.update(rcl);
 		} else {
@@ -54,29 +54,29 @@ public class DatabaseStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public Client get(Server server, String streamId) {
+	public StreamClient get(Server server, String streamId) {
 		return clientDao.getClientByServerAndStreamId(server, streamId);
 	}
 
 	@Override
-	public List<Client> getClientsByPublicSID(Server server, String publicSID) {
+	public List<StreamClient> getClientsByPublicSID(Server server, String publicSID) {
 		return clientDao.getClientsByPublicSIDAndServer(server, publicSID);
 	}
 
 	@Override
-	public Map<Long, List<Client>> getClientsByPublicSID(String publicSID) {
-		Map<Long, List<Client>> returnMap = new HashMap<>();
-		List<Client> clientList = clientDao.getClientsByPublicSID(publicSID);
-		for (Client cl : clientList) {
+	public Map<Long, List<StreamClient>> getClientsByPublicSID(String publicSID) {
+		Map<Long, List<StreamClient>> returnMap = new HashMap<>();
+		List<StreamClient> clientList = clientDao.getClientsByPublicSID(publicSID);
+		for (StreamClient cl : clientList) {
 			if (cl.getServer() == null) {
-				List<Client> clList = returnMap.get(null);
+				List<StreamClient> clList = returnMap.get(null);
 				if (clList == null) {
 					clList = new ArrayList<>();
 				}
 				clList.add(cl);
 				returnMap.put(null, clList);
 			} else {
-				List<Client> clList = returnMap.get(cl.getServer().getId());
+				List<StreamClient> clList = returnMap.get(cl.getServer().getId());
 				if (clList == null) {
 					clList = new ArrayList<>();
 				}
@@ -88,27 +88,27 @@ public class DatabaseStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public Collection<Client> getClients() {
+	public Collection<StreamClient> getClients() {
 		return clientDao.getClients();
 	}
 
 	@Override
-	public Collection<Client> getClientsWithServer() {
+	public Collection<StreamClient> getClientsWithServer() {
 		return clientDao.getClientsWithServer();
 	}
 
 	@Override
-	public Collection<Client> getClientsByServer(Server server) {
+	public Collection<StreamClient> getClientsByServer(Server server) {
 		return clientDao.getClientsByServer(server);
 	}
 
 	@Override
-	public List<Client> getClientsByUserId(Server server, Long userId) {
+	public List<StreamClient> getClientsByUserId(Server server, Long userId) {
 		return clientDao.getClientsByUserId(server, userId);
 	}
 
 	@Override
-	public List<Client> getClientsByRoomId(Long roomId) {
+	public List<StreamClient> getClientsByRoomId(Long roomId) {
 		return clientDao.getClientsByRoomId(roomId);
 	}
 
@@ -128,7 +128,7 @@ public class DatabaseStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public Collection<Client> values() {
+	public Collection<StreamClient> values() {
 		return clientDao.getClients();
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/HashMapStore.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/HashMapStore.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/HashMapStore.java
index c896b34..57a0c25 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/HashMapStore.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/HashMapStore.java
@@ -29,7 +29,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -52,7 +52,7 @@ import org.slf4j.Logger;
 public class HashMapStore implements IClientPersistenceStore {
 	protected static final Logger log = Red5LoggerFactory.getLogger(HashMapStore.class, webAppRootKey);
 
-	private Map<String, Client> clientsByStreamId = new ConcurrentHashMap<>();
+	private Map<String, StreamClient> clientsByStreamId = new ConcurrentHashMap<>();
 
 	@Override
 	public void clear() {
@@ -60,7 +60,7 @@ public class HashMapStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public void put(String streamId, Client rcl) {
+	public void put(String streamId, StreamClient rcl) {
 		clientsByStreamId.put(rcl.getStreamid(), rcl);
 	}
 
@@ -70,15 +70,15 @@ public class HashMapStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public Client get(Server server, String streamId) {
+	public StreamClient get(Server server, String streamId) {
 		return clientsByStreamId.get(streamId);
 	}
 
 	@Override
-	public List<Client> getClientsByPublicSID(Server server, String publicSID) {
-		List<Client> clientList = new ArrayList<>();
-		for (Map.Entry<String, Client> e: clientsByStreamId.entrySet()) {
-			Client cl = e.getValue();
+	public List<StreamClient> getClientsByPublicSID(Server server, String publicSID) {
+		List<StreamClient> clientList = new ArrayList<>();
+		for (Map.Entry<String, StreamClient> e: clientsByStreamId.entrySet()) {
+			StreamClient cl = e.getValue();
 			if (cl.getPublicSID().equals(publicSID)) {
 				clientList.add(cl);
 			}
@@ -87,11 +87,11 @@ public class HashMapStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public Map<Long,List<Client>> getClientsByPublicSID(String publicSID) {
-		Map<Long,List<Client>> clientMapList = new HashMap<>();
-		List<Client> clientList = new ArrayList<>();
-		for (Map.Entry<String, Client> e: clientsByStreamId.entrySet()) {
-			Client cl = e.getValue();
+	public Map<Long,List<StreamClient>> getClientsByPublicSID(String publicSID) {
+		Map<Long,List<StreamClient>> clientMapList = new HashMap<>();
+		List<StreamClient> clientList = new ArrayList<>();
+		for (Map.Entry<String, StreamClient> e: clientsByStreamId.entrySet()) {
+			StreamClient cl = e.getValue();
 			if (cl.getPublicSID().equals(publicSID)) {
 				clientList.add(cl);
 			}
@@ -101,27 +101,27 @@ public class HashMapStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public Collection<Client> getClients() {
+	public Collection<StreamClient> getClients() {
 		return clientsByStreamId.values();
 	}
 
 	@Override
-	public Collection<Client> getClientsWithServer() {
+	public Collection<StreamClient> getClientsWithServer() {
 		//there is no server object to be loaded, memory cache means
 		//there is no cluster enabled
 		return getClients();
 	}
 
 	@Override
-	public Collection<Client> getClientsByServer(Server server) {
+	public Collection<StreamClient> getClientsByServer(Server server) {
 		return clientsByStreamId.values();
 	}
 
 	@Override
-	public List<Client> getClientsByUserId(Server server, Long userId) {
-		List<Client> clientList = new ArrayList<>();
-		for (Map.Entry<String, Client> e: clientsByStreamId.entrySet()) {
-			Client cl = e.getValue();
+	public List<StreamClient> getClientsByUserId(Server server, Long userId) {
+		List<StreamClient> clientList = new ArrayList<>();
+		for (Map.Entry<String, StreamClient> e: clientsByStreamId.entrySet()) {
+			StreamClient cl = e.getValue();
 			if (cl.getUserId().equals(userId)) {
 				clientList.add(cl);
 			}
@@ -130,10 +130,10 @@ public class HashMapStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public  List<Client> getClientsByRoomId(Long roomId) {
-		List<Client> clientList = new ArrayList<>();
-		for (Map.Entry<String, Client> e: clientsByStreamId.entrySet()) {
-			Client cl = e.getValue();
+	public  List<StreamClient> getClientsByRoomId(Long roomId) {
+		List<StreamClient> clientList = new ArrayList<>();
+		for (Map.Entry<String, StreamClient> e: clientsByStreamId.entrySet()) {
+			StreamClient cl = e.getValue();
 			if (cl.getRoomId() != null && cl.getRoomId().equals(roomId)) {
 				clientList.add(cl);
 			}
@@ -157,7 +157,7 @@ public class HashMapStore implements IClientPersistenceStore {
 	}
 
 	@Override
-	public Collection<Client> values() {
+	public Collection<StreamClient> values() {
 		return clientsByStreamId.values();
 	}
 
@@ -194,8 +194,8 @@ public class HashMapStore implements IClientPersistenceStore {
 	@Override
 	public List<Long> getRoomsIdsByServer(Server server) {
 		Set<Long> rooms = new HashSet<>();
-		for (Map.Entry<String, Client> e: clientsByStreamId.entrySet()) {
-			Client cl = e.getValue();
+		for (Map.Entry<String, StreamClient> e: clientsByStreamId.entrySet()) {
+			StreamClient cl = e.getValue();
 			Long roomId = cl.getRoomId();
 			if (roomId != null && roomId.longValue() > 0 && !rooms.contains(roomId)) {
 				rooms.add(roomId);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/IClientPersistenceStore.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/IClientPersistenceStore.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/IClientPersistenceStore.java
index a511680..5ca0634 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/IClientPersistenceStore.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/store/IClientPersistenceStore.java
@@ -22,7 +22,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 
 public interface IClientPersistenceStore {
@@ -41,7 +41,7 @@ public interface IClientPersistenceStore {
 	 * @param streamId
 	 * @param rcl
 	 */
-	void put(String streamId, Client rcl);
+	void put(String streamId, StreamClient rcl);
 	
 	/**
 	 * 
@@ -58,7 +58,7 @@ public interface IClientPersistenceStore {
 	 * @param streamId
 	 * @return will return null if the client does not exist in the list
 	 */
-	Client get(Server server, String streamId);
+	StreamClient get(Server server, String streamId);
 
 	/**
 	 * 
@@ -66,7 +66,7 @@ public interface IClientPersistenceStore {
 	 * @param publicSID
 	 * @return will return an empty list if nothing available
 	 */
-	List<Client> getClientsByPublicSID(Server server, String publicSID);
+	List<StreamClient> getClientsByPublicSID(Server server, String publicSID);
 
 	/**
 	 * Searches for the publicSID across all servers
@@ -74,9 +74,9 @@ public interface IClientPersistenceStore {
 	 * @param publicSID
 	 * @return will return a map with the serverId as key and the RoomClients as list in the value
 	 */
-	Map<Long, List<Client>> getClientsByPublicSID(String publicSID);
+	Map<Long, List<StreamClient>> getClientsByPublicSID(String publicSID);
 
-	Collection<Client> getClients();
+	Collection<StreamClient> getClients();
 	
 	/**
 	 * get all clients by a specific {@link Server}
@@ -84,7 +84,7 @@ public interface IClientPersistenceStore {
 	 * @param server
 	 * @return will return an empty map if nothing available
 	 */
-	Collection<Client> getClientsByServer(Server server);
+	Collection<StreamClient> getClientsByServer(Server server);
 
 	/**
 	 * 
@@ -92,7 +92,7 @@ public interface IClientPersistenceStore {
 	 * @param userId
 	 * @return will return an empty list if nothing available
 	 */
-	Collection<Client> getClientsByUserId(Server server, Long userId);
+	Collection<StreamClient> getClientsByUserId(Server server, Long userId);
 
 	/**
 	 * 
@@ -101,7 +101,7 @@ public interface IClientPersistenceStore {
 	 * @param roomId
 	 * @return will return an empty map if nothing available
 	 */
-	List<Client> getClientsByRoomId(Long roomId);
+	List<StreamClient> getClientsByRoomId(Long roomId);
 
 	void remove(Server server, String streamId);
 
@@ -109,7 +109,7 @@ public interface IClientPersistenceStore {
 
 	int sizeByServer(Server server);
 
-	Collection<Client> values();
+	Collection<StreamClient> values();
 	
 	/**
 	 * Get some session statistics
@@ -135,5 +135,5 @@ public interface IClientPersistenceStore {
 	 * 
 	 * @return
 	 */
-	Collection<Client> getClientsWithServer();
+	Collection<StreamClient> getClientsWithServer();
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java
new file mode 100644
index 0000000..508bd4a
--- /dev/null
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/RoomHelper.java
@@ -0,0 +1,42 @@
+/*
+ * 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.core.util;
+
+import org.apache.openmeetings.db.dao.server.ISessionManager;
+import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
+
+import com.github.openjson.JSONObject;
+
+public class RoomHelper {
+
+	public static JSONObject videoJson(Client c, boolean self, String sid, ISessionManager mgr, boolean share) {
+		JSONObject json = c.toJson(self).put("sid", sid);
+		if (share) {
+			StreamClient sc = mgr.getClientByPublicSID(c.getUid(), null); //TODO check server
+
+			json.put("screenShare", true)
+				.put("uid", sc.getPublicSID()) // unique screen-sharing ID
+				.put("broadcastId", sc.getBroadCastID())
+				.put("width", sc.getVWidth())
+				.put("height", sc.getVHeight());
+		}
+		return json;
+	}
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
index a266a42..799b2aa 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
@@ -24,7 +24,7 @@ import java.util.function.Supplier;
 
 import javax.servlet.ServletContext;
 
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.wicket.request.IExceptionMapper;
 import org.apache.wicket.request.IRequestMapper;
@@ -40,7 +40,7 @@ public interface IApplication {
 	String getOmString(String key, long languageId);
 	String getOmString(String key, final Locale loc, String... params);
 	org.apache.openmeetings.db.entity.basic.Client getOmClient(String uid);
-	Client updateClient(Client rcl, boolean forceSize);
+	StreamClient updateClient(StreamClient rcl, boolean forceSize);
 	List<org.apache.openmeetings.db.entity.basic.Client> getOmRoomClients(Long roomId);
 	List<org.apache.openmeetings.db.entity.basic.Client> getOmClients(Long userId);
 	String getOmContactsLink();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/ClientDao.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/ClientDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/ClientDao.java
index 66996af..99af2cb 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/ClientDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/ClientDao.java
@@ -26,7 +26,7 @@ import javax.persistence.PersistenceContext;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -54,17 +54,17 @@ public class ClientDao {
 			executeUpdate();
 	}
 
-	public Client add(Client entity) {
+	public StreamClient add(StreamClient entity) {
 		em.persist(entity);
 		return entity;
 	}
 
-	public Client update(Client entity) {
+	public StreamClient update(StreamClient entity) {
 		em.merge(entity);
 		return entity;
 	}
 
-	public void delete(Client entity) {
+	public void delete(StreamClient entity) {
 		Query q = em.createNamedQuery("deletedById");
 		q.setParameter("id", entity.getId());
 		q.executeUpdate();
@@ -102,11 +102,11 @@ public class ClientDao {
 	 * @param streamId
 	 * @return
 	 */
-	public Client getClientByServerAndStreamId(Server server, String streamId) {
-		TypedQuery<Client> q = em.createNamedQuery("getClientByServerAndStreamId", Client.class);
+	public StreamClient getClientByServerAndStreamId(Server server, String streamId) {
+		TypedQuery<StreamClient> q = em.createNamedQuery("getClientByServerAndStreamId", StreamClient.class);
 		q.setParameter("streamid", streamId);
 		q.setParameter("server", server);
-		List<Client> ll = q.getResultList();
+		List<StreamClient> ll = q.getResultList();
 		if (ll.size() == 1) {
 			return ll.get(0);
 		} else if (ll.size() == 0) {
@@ -115,42 +115,42 @@ public class ClientDao {
 		throw new RuntimeException("more then one client was found streamId "+ streamId + " server "+server);
 	}
 
-	public List<Client> getClientsByPublicSIDAndServer(Server server, String publicSID) {
-		TypedQuery<Client> q = em.createNamedQuery("getClientsByPublicSIDAndServer", Client.class);
+	public List<StreamClient> getClientsByPublicSIDAndServer(Server server, String publicSID) {
+		TypedQuery<StreamClient> q = em.createNamedQuery("getClientsByPublicSIDAndServer", StreamClient.class);
 		q.setParameter("server", server);
 		q.setParameter("publicSID", publicSID);
 		return q.getResultList();
 	}
 
-	public List<Client> getClientsByPublicSID(String publicSID) {
-		TypedQuery<Client> q = em.createNamedQuery("getClientsByPublicSID", Client.class);
+	public List<StreamClient> getClientsByPublicSID(String publicSID) {
+		TypedQuery<StreamClient> q = em.createNamedQuery("getClientsByPublicSID", StreamClient.class);
 		q.setParameter("publicSID", publicSID);
 		return q.getResultList();
 	}
 
-	public List<Client> getClientsByServer(Server server) {
-		TypedQuery<Client> q = em.createNamedQuery("getClientsByServer", Client.class);
+	public List<StreamClient> getClientsByServer(Server server) {
+		TypedQuery<StreamClient> q = em.createNamedQuery("getClientsByServer", StreamClient.class);
 		q.setParameter("server", server);
 		return q.getResultList();
 	}
 
-	public List<Client> getClients() {
-		return em.createNamedQuery("getClients", Client.class).getResultList();
+	public List<StreamClient> getClients() {
+		return em.createNamedQuery("getClients", StreamClient.class).getResultList();
 	}
 
-	public List<Client> getClientsWithServer() {
-		return em.createNamedQuery("getClientsWithServer", Client.class).getResultList();
+	public List<StreamClient> getClientsWithServer() {
+		return em.createNamedQuery("getClientsWithServer", StreamClient.class).getResultList();
 	}
 
-	public List<Client> getClientsByUserId(Server server, Long userId) {
-		TypedQuery<Client> q = em.createNamedQuery("getClientsByUserId", Client.class);
+	public List<StreamClient> getClientsByUserId(Server server, Long userId) {
+		TypedQuery<StreamClient> q = em.createNamedQuery("getClientsByUserId", StreamClient.class);
 		q.setParameter("server", server);
 		q.setParameter("userId", userId);
 		return q.getResultList();
 	}
 
-	public List<Client> getClientsByRoomId(Long roomId) {
-		TypedQuery<Client> q = em.createNamedQuery("getClientsByRoomId", Client.class);
+	public List<StreamClient> getClientsByRoomId(Long roomId) {
+		TypedQuery<StreamClient> q = em.createNamedQuery("getClientsByRoomId", StreamClient.class);
 		q.setParameter("roomId", roomId);
 		return q.getResultList();
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
index 698dbe0..5bd1be2 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
@@ -23,11 +23,11 @@ import java.util.List;
 
 import org.apache.openmeetings.db.dto.basic.SearchResult;
 import org.apache.openmeetings.db.dto.server.ClientSessionInfo;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Server;
 
 /**
- * Methods to add/get/remove {@link Client}s to the session
+ * Methods to add/get/remove {@link StreamClient}s to the session
  *
  *
  * @author sebawagner
@@ -42,7 +42,7 @@ public interface ISessionManager {
 	 */
 	void sessionStart();
 
-	Client add(Client c, Server server);
+	StreamClient add(StreamClient c, Server server);
 	/**
 	 * add a new client item
 	 *
@@ -54,16 +54,16 @@ public interface ISessionManager {
 	 * @param server
 	 * @return
 	 */
-	Client addClientListItem(String streamId, String scopeName, int remotePort, String remoteAddress, String swfUrl, Server server);
+	StreamClient addClientListItem(String streamId, String scopeName, int remotePort, String remoteAddress, String swfUrl, Server server);
 
-	Collection<Client> getClients();
+	Collection<StreamClient> getClients();
 
 	/**
 	 * loads the server into the client (only if database cache is used)
 	 *
 	 * @return
 	 */
-	Collection<Client> getClientsWithServer();
+	Collection<StreamClient> getClientsWithServer();
 
 	/**
 	 * Get a client by its streamId
@@ -72,7 +72,7 @@ public interface ISessionManager {
 	 * @param server
 	 * @return
 	 */
-	Client getClientByStreamId(String streamId, Server server);
+	StreamClient getClientByStreamId(String streamId, Server server);
 
 	/**
 	 * get a client by its publicSID and the server,
@@ -81,7 +81,7 @@ public interface ISessionManager {
 	 * @param server
 	 * @return
 	 */
-	Client getClientByPublicSID(String publicSID, Server server);
+	StreamClient getClientByPublicSID(String publicSID, Server server);
 
 	/**
 	 * same as {@link #getClientByPublicSID(String, boolean, Server)} but it ignores
@@ -105,7 +105,7 @@ public interface ISessionManager {
 	 *             then this call would return a list not a single user
 	 */
 	@Deprecated
-	Client getClientByUserId(Long userId);
+	StreamClient getClientByUserId(Long userId);
 
 	/**
 	 * Update the session object of the audio/video-connection and additionally
@@ -116,7 +116,7 @@ public interface ISessionManager {
 	 * @param rcm
 	 * @return
 	 */
-	boolean updateAVClientByStreamId(String streamId, Client rcm, Server server);
+	boolean updateAVClientByStreamId(String streamId, StreamClient rcm, Server server);
 
 	/**
 	 * Update the session object
@@ -131,7 +131,7 @@ public interface ISessionManager {
 	 *            true means the count for the room has to be updated
 	 * @return
 	 */
-	boolean updateClientByStreamId(String streamId, Client rcm, boolean updateRoomCount, Server server);
+	boolean updateClientByStreamId(String streamId, StreamClient rcm, boolean updateRoomCount, Server server);
 
 	/**
 	 * Remove a client from the session store
@@ -149,9 +149,9 @@ public interface ISessionManager {
 	 * @param roomId
 	 * @return
 	 */
-	List<Client> getClientListByRoom(Long roomId);
+	List<StreamClient> getClientListByRoom(Long roomId);
 
-	Collection<Client> getClientListByRoomAll(Long roomId);
+	Collection<StreamClient> getClientListByRoomAll(Long roomId);
 
 	/**
 	 * get the current Moderator in this room
@@ -159,7 +159,7 @@ public interface ISessionManager {
 	 * @param roomname
 	 * @return
 	 */
-	List<Client> getCurrentModeratorByRoom(Long roomId);
+	List<StreamClient> getCurrentModeratorByRoom(Long roomId);
 
 	/**
 	 * Get list of current client sessions
@@ -170,7 +170,7 @@ public interface ISessionManager {
 	 * @param asc
 	 * @return
 	 */
-	SearchResult<Client> getListByStartAndMax(int start, int max, String orderby, boolean asc);
+	SearchResult<StreamClient> getListByStartAndMax(int start, int max, String orderby, boolean asc);
 
 	/**
 	 * returns number of current users recording

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/SessiondataDao.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/SessiondataDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/SessiondataDao.java
index 3226433..aba491d 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/SessiondataDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/SessiondataDao.java
@@ -28,7 +28,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.persistence.TypedQuery;
 
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -205,7 +205,7 @@ public class SessiondataDao {
 	 */
 	public void clearSessionByRoomId(Long roomId) {
 		try {
-			for (Client rcl : sessionManager.getClientListByRoom(roomId)) {
+			for (StreamClient rcl : sessionManager.getClientListByRoom(roomId)) {
 				String aux = rcl.getSwfurl();
 
 				//FIXME TODO this need to be refactored !

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomStatus.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomStatus.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomStatus.java
index 98831a2..1c5bc51 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomStatus.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomStatus.java
@@ -20,18 +20,18 @@ package org.apache.openmeetings.db.dto.room;
 
 import java.util.List;
 
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 
 public class RoomStatus {
-	List<Client> clientList;
+	List<StreamClient> clientList;
 	BrowserStatus browserStatus;
 	
 	public RoomStatus() {}
 	
-	public List<Client> getClientList() {
+	public List<StreamClient> getClientList() {
 		return clientList;
 	}
-	public void setClientList(List<Client> clientList) {
+	public void setClientList(List<StreamClient> clientList) {
 		this.clientList = clientList;
 	}
 	public BrowserStatus getBrowserStatus() {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/server/ClientSessionInfo.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/server/ClientSessionInfo.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/server/ClientSessionInfo.java
index cd437e7..d257d8c 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/server/ClientSessionInfo.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/server/ClientSessionInfo.java
@@ -18,26 +18,26 @@
  */
 package org.apache.openmeetings.db.dto.server;
 
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 
 
 public class ClientSessionInfo {
 	
-	private Client rcl;
+	private StreamClient rcl;
 	public Long serverId;
 	
 	public ClientSessionInfo() {}
 	
-	public ClientSessionInfo(Client rcl, Long serverId) {
+	public ClientSessionInfo(StreamClient rcl, Long serverId) {
 		super();
 		this.rcl = rcl;
 		this.serverId = serverId;
 	}
 	
-	public Client getRcl() {
+	public StreamClient getRcl() {
 		return rcl;
 	}
-	public void setRcl(Client rcl) {
+	public void setRcl(StreamClient rcl) {
 		this.rcl = rcl;
 	}
 	public Long getServerId() {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
index 19e9787..0950125 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
@@ -26,6 +26,7 @@ import java.util.UUID;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Room.Right;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.wicket.protocol.ws.api.registry.IKey;
 import org.apache.wicket.util.string.Strings;
@@ -34,7 +35,7 @@ import com.github.openjson.JSONArray;
 import com.github.openjson.JSONObject;
 
 /**
- * Temporary class, later will be merged with {@link org.apache.openmeetings.db.entity.room.Client}
+ * Temporary class, later will be merged with {@link org.apache.openmeetings.db.entity.room.StreamClient}
  * @author solomax
  *
  */
@@ -80,7 +81,7 @@ public class Client implements IClient {
 		sid = UUID.randomUUID().toString();
 	}
 
-	public Client(org.apache.openmeetings.db.entity.room.Client rcl, UserDao dao) {
+	public Client(StreamClient rcl, UserDao dao) {
 		this.sessionId = UUID.randomUUID().toString();
 		this.pageId = 0;
 		this.user = dao.get(rcl.getUserId());

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/a260f5a8/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
index 3e72c0e..d052a8b 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
@@ -22,7 +22,7 @@ import org.apache.openmeetings.db.entity.IDataProviderEntity;
 
 /**
  * Temporary interface, will be removed after 2 types of cliens will be merged
- * {@link org.apache.openmeetings.db.entity.room.Client}
+ * {@link org.apache.openmeetings.db.entity.room.StreamClient}
  * {@link org.apache.openmeetings.db.entity.basic.Client}
  * @author solomax
  *