screenshare2.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. ScreenShare = (function() {
  2. function encode(cells) {
  3. const codec = new mxCodec();
  4. const encoded = codec.encode(cells);
  5. return mxUtils.getXml(encoded);
  6. };
  7. return class {
  8. constructor(client, graph, confirm, alert) {
  9. this.graph = graph;
  10. this.sharingWith = {};
  11. this.confirm = confirm;
  12. this.alert = alert;
  13. let listenerEnabled = true;
  14. const shareEvent = serializer => {
  15. // return new event listener for mxEventSource:
  16. return (source, eventObj) => {
  17. if (listenerEnabled) {
  18. const props = serializer(eventObj.properties);
  19. if (props !== undefined) {
  20. Object.keys(this.sharingWith).forEach(peer => {
  21. this.p2p.send(peer, "push_edit", {
  22. event: eventObj.name,
  23. props,
  24. }, (err, data) => {
  25. if (err) {}
  26. else {}
  27. });
  28. })
  29. }
  30. }
  31. };
  32. };
  33. // Our event listener, serializing and sending events to other peers
  34. this.graph.model.addListener(mxEvent.NOTIFY,
  35. shareEvent(({edit: {changes}}) => changes.map(change => encode(change))));
  36. // Handler for incoming requests from other peers
  37. this.p2p = new PeerToPeer(client, {
  38. // incoming request from another peer
  39. "push_edit": (from, {event, props}, reply) => {
  40. if (this.sharingWith[from]) {
  41. // temporary disable our listener, we don't want to echo our received edit
  42. listenerEnabled = false;
  43. ({
  44. [mxEvent.NOTIFY]: encodedChanges => {
  45. const codec = new mxCodec();
  46. codec.lookup = id => this.graph.model.cells[id];
  47. const changes = encodedChanges.map(encoded => {
  48. const parsedXml = mxUtils.parseXml(encoded).documentElement;
  49. const change = codec.decode(parsedXml);
  50. change.model = this.graph.model;
  51. return change
  52. });
  53. console.log(changes);
  54. changes.forEach(change => this.graph.model.execute(change));
  55. },
  56. }[event])(props);
  57. listenerEnabled = true;
  58. reply(); // acknowledge
  59. }
  60. },
  61. "init_screenshare": (from, graphSerialized, reply) => {
  62. const yes = () => {
  63. const doc = mxUtils.parseXml(graphSerialized);
  64. const codec = new mxCodec(doc);
  65. codec.decode(doc.documentElement, graph.model);
  66. this.sharingWith[from] = true;
  67. reply(); // acknowledge
  68. this.alert("You are now <b>screen sharing</b> with " + shortUUID(from));
  69. };
  70. const no = () => {
  71. reply("denied")
  72. };
  73. this.confirm(`Peer ${shortUUID(from)} wants to <b>screen share</b>.<br />Your diagram will be erased and replaced by his/hers.<br /><br />Accept?`, yes, no);
  74. },
  75. });
  76. }
  77. initshare(peer) {
  78. const graphSerialized = encode(this.graph.model);
  79. this.p2p.send(peer, "init_screenshare", graphSerialized, (err, data) => {
  80. if (err) {
  81. this.alert(err)
  82. }
  83. else {
  84. this.alert("Accepted: You are now <b>screen sharing</b> with " + shortUUID(peer));
  85. this.sharingWith[peer] = true;
  86. }
  87. });
  88. }
  89. }
  90. })();