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/03/25 11:11:55 UTC

svn commit: r1788661 - in /openmeetings/application/trunk: openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/ openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/

Author: solomax
Date: Sat Mar 25 11:11:55 2017
New Revision: 1788661

URL: http://svn.apache.org/viewvc?rev=1788661&view=rev
Log:
[OPENMEETINGS-551] sync object create is implemented

Modified:
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java?rev=1788661&r1=1788660&r2=1788661&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java Sat Mar 25 11:11:55 2017
@@ -30,6 +30,8 @@ import java.util.concurrent.ConcurrentHa
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
+import com.github.openjson.JSONObject;
+
 public class Whiteboard {
 	private static final Logger log = Red5LoggerFactory.getLogger(Whiteboard.class, webAppRootKey);
 	private long id;
@@ -37,7 +39,7 @@ public class Whiteboard {
 	private Integer y = 0;
 	private Integer zoom = 100;
 	private Boolean fullFit = true;
-	private Map<String, List<Object>> roomItems = new ConcurrentHashMap<>();
+	private Map<String, JSONObject> roomItems = new ConcurrentHashMap<>();
 	private Date created = new Date();
 	private int zIndex = 1;
 	private String name;
@@ -102,26 +104,19 @@ public class Whiteboard {
 	}
 
 	//getter is required, otherwise roomItems are not available in red5
-	public Map<String, List<Object>> getRoomItems() {
+	public Map<String, JSONObject> getRoomItems() {
 		return roomItems;
 	}
 
-	public void add(String oid, List<Object> actionObject) {
-		Object type = actionObject.size() > 0 ? actionObject.get(0) : "";
-		if (actionObject.size() > 8 && ("swf".equals(type) || "image".equals(type) || "flv".equals(type))) {
-			Integer zInd = (Integer)actionObject.get(actionObject.size() - 8);
-			if (zInd == null || zInd == 0 || zInd < zIndex) {
-				actionObject.set(actionObject.size() - 8, zIndex++);
-			}
-		}
-		roomItems.put(oid, actionObject);
+	public void add(String uid, JSONObject obj) {
+		roomItems.put(uid, obj);
 	}
 
-	public List<Object> get(String oid) {
-		return roomItems.get(oid);
+	public JSONObject get(String uid) {
+		return roomItems.get(uid);
 	}
 
-	public Set<Entry<String, List<Object>>> entrySet() {
+	public Set<Entry<String, JSONObject>> entrySet() {
 		return roomItems.entrySet();
 	}
 

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java?rev=1788661&r1=1788660&r2=1788661&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java Sat Mar 25 11:11:55 2017
@@ -25,10 +25,12 @@ import static org.apache.wicket.ajax.att
 
 import java.util.Arrays;
 import java.util.Map.Entry;
+import java.util.function.Predicate;
 
 import org.apache.openmeetings.core.data.whiteboard.WhiteboardCache;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dto.room.Whiteboard;
+import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.web.room.RoomPanel;
@@ -57,10 +59,12 @@ public class WbPanel extends Panel {
 	private final static ResourceReference WB_JS_REFERENCE = new JavaScriptResourceReference(WbPanel.class, "wb.js");
 	private final static ResourceReference FABRIC_JS_REFERENCE = new JavaScriptResourceReference(WbPanel.class, "fabric.js");
 	private boolean readOnly = true;
+	private final Long roomId;
 	private final RoomPanel rp;
 	private enum Action {
 		createWb
 		, removeWb
+		, createObj
 	}
 	private final AbstractDefaultAjaxBehavior wbAction = new AbstractDefaultAjaxBehavior() {
 		private static final long serialVersionUID = 1L;
@@ -71,22 +75,36 @@ public class WbPanel extends Panel {
 				Action a = Action.valueOf(getRequest().getRequestParameters().getParameterValue(PARAM_ACTION).toString());
 				StringValue sv = getRequest().getRequestParameters().getParameterValue(PARAM_OBJ);
 				JSONObject obj = sv.isEmpty() ? new JSONObject() : new JSONObject(sv.toString());
+				if (Action.createObj == a) {
+					if ("pointer".equals(obj.getJSONObject("obj").getString("type"))) {
+						sendWbOthers(String.format("WbArea.createObj(%s);", obj.toString()));
+						return;
+					}
+				}
 
 				//wb-right
 				if (rp.getClient().hasRight(Right.whiteBoard)) {
 					switch (a) {
 						case createWb:
 						{
-							Whiteboard wb = getBean(WhiteboardCache.class).add(rp.getRoom().getId(), rp.getClient().getUser().getLanguageId());
-							sendWb(getAddWbScript(wb.getId(), wb.getName()).toString());
+							Whiteboard wb = getBean(WhiteboardCache.class).add(roomId, rp.getClient().getUser().getLanguageId());
+							sendWbAll(getAddWbScript(wb.getId(), wb.getName()).toString());
 						}
 							break;
 						case removeWb:
 						{
 							long _id = obj.optLong("id", -1);
 							Long id = _id < 0 ? null : _id;
-							getBean(WhiteboardCache.class).remove(rp.getRoom().getId(), id);
-							sendWb(String.format("WbArea.remove(%s);", id));
+							getBean(WhiteboardCache.class).remove(roomId, id);
+							sendWbAll(String.format("WbArea.remove(%s);", id));
+						}
+							break;
+						case createObj:
+						{
+							Whiteboard wb = getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
+							JSONObject o = obj.getJSONObject("obj");
+							wb.add(o.getString("uid"), o);
+							sendWbOthers(String.format("WbArea.createObj(%s);", obj.toString()));
 						}
 							break;
 					}
@@ -100,9 +118,10 @@ public class WbPanel extends Panel {
 	public WbPanel(String id, RoomPanel rp) {
 		super(id);
 		this.rp = rp;
+		this.roomId = rp.getRoom().getId();
 		setOutputMarkupId(true);
 
-		getBean(WhiteboardCache.class).get(rp.getRoom().getId()).getWhiteboards();//TODO
+		getBean(WhiteboardCache.class).get(roomId).getWhiteboards();//TODO
 		add(new ListView<String>("clipart", Arrays.asList(OmFileHelper.getPublicClipartsDir().list())) {
 			private static final long serialVersionUID = 1L;
 
@@ -123,19 +142,28 @@ public class WbPanel extends Panel {
 		response.render(JavaScriptHeaderItem.forReference(WB_JS_REFERENCE));
 		response.render(new PriorityHeaderItem(getNamedFunction(FUNC_ACTION, wbAction, explicit(PARAM_ACTION), explicit(PARAM_OBJ))));
 		StringBuilder sb = new StringBuilder("WbArea.init();");
-		for (Entry<Long, Whiteboard> entry : getBean(WhiteboardCache.class).list(rp.getRoom().getId(), rp.getClient().getUser().getLanguageId())) {
+		for (Entry<Long, Whiteboard> entry : getBean(WhiteboardCache.class).list(roomId, rp.getClient().getUser().getLanguageId())) {
 			sb.append(getAddWbScript(entry.getKey(), entry.getValue().getName()));
 		}
 		response.render(OnDomReadyHeaderItem.forScript(sb));
 	}
 
-	private void sendWb(CharSequence func) {
+	private void sendWbAll(CharSequence func) {
+		sendWb(func, null);
+	}
+
+	private void sendWbOthers(CharSequence func) {
+		sendWb(func, c -> !rp.getClient().getUid().equals(c.getUid()));
+	}
+
+	private void sendWb(CharSequence func, Predicate<Client> check) {
 		WebSocketHelper.sendRoom(
-				rp.getRoom().getId()
+				roomId
 				, new JSONObject()
 						.put("type", "wb")
 						.put("func", func)
 						.toString()
+				, check
 			);
 	}
 

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js?rev=1788661&r1=1788660&r2=1788661&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js Sat Mar 25 11:11:55 2017
@@ -60,11 +60,20 @@ var Pointer = function(canvas, s) {
 		}
 	};
 }
-var APointer = function(canvas, user) {
-	var pointer = {};
-	pointer.mouseUp = function(o) {
-		var ptr = canvas.getPointer(o.e);
-		fabric.Image.fromURL('./css/images/menupointer.png', function(img) {
+var Base = function(canvas) {
+	var base = {};
+	base.objectCreated = function(o) {
+		o.uid = UUID.generate();
+		canvas.trigger("wb:object:created", o);
+		return o.uid;
+	}
+	return base;
+}
+var APointer = function(canvas) {
+	var pointer = Base(canvas);
+	pointer.user = '';
+	pointer.create = function(_cnvs, o) {
+		fabric.Image.fromURL('./css/images/pointer.png', function(img) {
 			img.set({
 				left:15
 				, originX: 'right'
@@ -86,56 +95,70 @@ var APointer = function(canvas, user) {
 				, originX: 'center'
 				, originY: 'center'
 			});
-			var text = new fabric.Text(user, {
+			var text = new fabric.Text(o.user, {
 				fontSize: 12
 				, left: 10
 				, originX: 'left'
 				, originY: 'bottom'
 			});
 			var group = new fabric.Group([circle1, circle2, img, text], {
-				left: ptr.x - 20
-				, top: ptr.y - 20
+				left: o.x - 20
+				, top: o.y - 20
 			});
-			canvas.add(group);
+			
+			_cnvs.add(group);
+			group.uid = o.uid;
+			group.loaded = !!o.loaded;
 
 			var count = 3;
 			function go(_cnt) {
 				if (_cnt < 0) {
-					canvas.remove(group);
+					_cnvs.remove(group);
 				}
 				circle1.set({radius: 3});
 				circle2.set({radius: 6});
 				circle1.animate(
 					'radius', '20'
 					, {
-						onChange: canvas.renderAll.bind(canvas)
+						onChange: _cnvs.renderAll.bind(_cnvs)
 						, duration: 1000
 						, onComplete: function() {go(_cnt - 1);}
 					});
 				circle2.animate(
 					'radius', '20'
 					, {
-						onChange: canvas.renderAll.bind(canvas)
+						onChange: _cnvs.renderAll.bind(_cnvs)
 						, duration: 1000
 					});
 			}
 			go(count);
 		});
 	}
+	pointer.mouseUp = function(o) {
+		var ptr = canvas.getPointer(o.e);
+		var obj = {
+			type: 'pointer'
+			, x: ptr.x
+			, y: ptr.y
+			, user: pointer.user
+		};
+		obj.uid = uid = pointer.objectCreated(obj);
+		pointer.create(canvas, obj);
+	}
 	pointer.activate = function() {
 		canvas.on('mouse:up', pointer.mouseUp);
+		pointer.user = $('.room.sidebar.left .user.list .current .name').text();
 	}
 	pointer.deactivate = function() {
 		canvas.off('mouse:up', pointer.mouseUp);
 	};
 	return pointer;
 }
-var Base = function() {
-	var base = {
-		fill: {enabled: true, color: '#FFFF33'}
-		, stroke: {enabled: true, color: '#FF6600', width: 5}
-		, opacity: 1
-	};
+var ShapeBase = function(canvas) {
+	var base = Base(canvas);
+	base.fill = {enabled: true, color: '#FFFF33'};
+	base.stroke = {enabled: true, color: '#FF6600', width: 5};
+	base.opacity = 1;
 	base.enableLineProps = function(s) {
 		var c = s.find('.wb-prop-color'), w = s.find('.wb-prop-width'), o = s.find('.wb-prop-opacity');
 		s.find('.wb-prop-fill').prop('disabled', true);
@@ -160,7 +183,7 @@ var Base = function() {
 	return base;
 }
 var Text = function(canvas, s) {
-	var text = Base();
+	var text = ShapeBase(canvas);
 	text.obj = null;
 
 	text.mouseDown = function(o) {
@@ -203,7 +226,7 @@ var Text = function(canvas, s) {
 	return text;
 }
 var Paint = function(canvas, s) {
-	var paint = Base();
+	var paint = ShapeBase(canvas);
 	paint.activate = function() {
 		canvas.isDrawingMode = true;
 		canvas.freeDrawingBrush.width = paint.stroke.width;
@@ -218,7 +241,7 @@ var Paint = function(canvas, s) {
 	return paint;
 }
 var Shape = function(canvas) {
-	var shape = Base();
+	var shape = ShapeBase(canvas);
 	shape.obj = null;
 	shape.isDown = false;
 	shape.orig = {x: 0, y: 0};
@@ -239,22 +262,31 @@ var Shape = function(canvas) {
 		shape.updateShape(pointer);
 		canvas.renderAll();
 	};
+	shape.updateCreated = function(o) {
+		return o;
+	};
 	shape.mouseUp = function(o) {
 		shape.isDown = false;
 		shape.obj.setCoords();
 		shape.obj.selectable = false;
+		canvas.renderAll();
+		shape.objectCreated(shape.obj);
 	};
 	shape.internalActivate = function() {};
 	shape.activate = function() {
-		canvas.on('mouse:down', shape.mouseDown);
-		canvas.on('mouse:move', shape.mouseMove);
-		canvas.on('mouse:up', shape.mouseUp);
+		canvas.on({
+			'mouse:down': shape.mouseDown
+			, 'mouse:move': shape.mouseMove
+			, 'mouse:up': shape.mouseUp
+		});
 		shape.internalActivate();
 	};
 	shape.deactivate = function() {
-		canvas.off('mouse:down', shape.mouseDown);
-		canvas.off('mouse:move', shape.mouseMove);
-		canvas.off('mouse:up', shape.mouseUup);
+		canvas.off({
+			'mouse:down': shape.mouseDown
+			, 'mouse:move': shape.mouseMove
+			, 'mouse:up': shape.mouseUp
+		});
 	};
 	return shape;
 };
@@ -487,7 +519,7 @@ var Wb = function() {
 			}
 		});
 		initToolBtn('pointer', true, Pointer(canvas, s));
-		initToolBtn('apointer', false, APointer(canvas, 'TEST USER')); //FIXME TODO
+		initToolBtn('apointer', false, APointer(canvas));
 		initToolBtn('text', false, Text(canvas, s));
 		initToolBtn('paint', false, Paint(canvas, s));
 		initToolBtn('line', false, Line(canvas, s));
@@ -566,22 +598,42 @@ var Wb = function() {
 	}
 
 	//events
+	var wbObjCreatedHandler = function (o) {
+		var json = {};
+		switch(o.type) {
+			case 'pointer':
+				json = o;
+				break;
+			default:
+				o.includeDefaultValues = false;
+				json = o.toJSON(['uid'])
+				break;
+		}
+		wbAction('createObj', JSON.stringify({
+			wbId: wbId
+			, obj: json
+		}));
+		//console.log('Wb Object Created', json, o);
+	};
 	var objAddedHandler = function (e) {
-		var obj = e.target;
-		console.log('Object Added', obj);
+		var o = e.target;
+		if (!!o.loaded) return;
+		switch(o.type) {
+			case 'i-text':
+				o.uid = UUID.generate();
+				wbObjCreatedHandler(o);
+				break;
+		}
 	};
 	var objModifiedHandler = function (e) {
 		var obj = e.target;
 		console.log('Object Modified', obj);
 	};
-	var objRemovedHandler = function (e) {
-		var obj = e.target;
-		console.log('Object Removed', obj);
-	};
-	var pathCreatedHandler = function (e) {
-		var obj = e.target;
-		console.log('Path Created', obj);
+	var pathCreatedHandler = function (o) {
+		o.path.uid = UUID.generate();
+		wbObjCreatedHandler(o.path);
 	};
+	/*TODO interactive text chage
 	var textEditedHandler = function (e) {
 		var obj = e.target;
 		console.log('Text Edit Exit', obj);
@@ -589,7 +641,7 @@ var Wb = function() {
 	var textChangedHandler = function (e) {
 		var obj = e.target;
 		console.log('Text Changed', obj);
-	};
+	};*/
 	return {
 		init: function(_wbId, tid) {
 			wbId = _wbId;
@@ -598,12 +650,14 @@ var Wb = function() {
 			c.attr('id', 'can-' + tid);
 			canvas = new fabric.Canvas(c.attr('id'));
 			//TODO create via WS canvas:cleared
-			canvas.on('object:added', objAddedHandler);
-			canvas.on('object:modified', objModifiedHandler);
-			canvas.on('object:removed', objRemovedHandler);
-			canvas.on('path:created', pathCreatedHandler);
-			canvas.on('text:editing:exited', textEditedHandler);
-			canvas.on('text:changed', textChangedHandler);
+			canvas.on({
+				'object:added': objAddedHandler
+				, 'object:modified': objModifiedHandler
+				, 'path:created': pathCreatedHandler
+				//, 'text:editing:exited': textEditedHandler
+				//, 'text:changed': textChangedHandler
+				, 'wb:object:created': wbObjCreatedHandler
+			});
 			internalInit(t);
 			setRoomSizes();
 		}
@@ -702,6 +756,30 @@ var WbArea = (function() {
 		});
 		wb.data(Wb()).data('init')(obj.id, tid);
 	};
+	self.createObj = function(json) {
+		var canvas = $('#' + getWbTabId(json.wbId)).data('getCanvas')();
+		var o = json.obj;
+		o.loaded = true;
+		switch(o.type) {
+			case 'pointer':
+				APointer().create(canvas, o);
+				break;
+			default:
+				//TODO will be reused on Load WB
+				fabric.util.enlivenObjects([o], function(objects) {
+					var origRenderOnAddRemove = canvas.renderOnAddRemove;
+					canvas.renderOnAddRemove = false;
+
+					objects.forEach(function(_o) {
+						canvas.add(_o);
+					});
+
+					canvas.renderOnAddRemove = origRenderOnAddRemove;
+					canvas.renderAll();
+				});
+				break;
+		}
+	};
 	self.remove = function(id) {
 		var tabId = getWbTabId(id);
 		tabs.find('li[aria-controls="' + tabId + '"]').remove();