You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Prezi.js 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. var ToolbarToggler = require("../toolbars/ToolbarToggler");
  2. var UIUtil = require("../util/UIUtil");
  3. var VideoLayout = require("../videolayout/VideoLayout");
  4. var messageHandler = require("../util/MessageHandler");
  5. var PreziPlayer = require("./PreziPlayer");
  6. var preziPlayer = null;
  7. var Prezi = {
  8. /**
  9. * Reloads the current presentation.
  10. */
  11. reloadPresentation: function() {
  12. var iframe = document.getElementById(preziPlayer.options.preziId);
  13. iframe.src = iframe.src;
  14. },
  15. /**
  16. * Returns <tt>true</tt> if the presentation is visible, <tt>false</tt> -
  17. * otherwise.
  18. */
  19. isPresentationVisible: function () {
  20. return ($('#presentation>iframe') != null
  21. && $('#presentation>iframe').css('opacity') == 1);
  22. },
  23. /**
  24. * Opens the Prezi dialog, from which the user could choose a presentation
  25. * to load.
  26. */
  27. openPreziDialog: function() {
  28. var myprezi = APP.xmpp.getPrezi();
  29. if (myprezi) {
  30. messageHandler.openTwoButtonDialog("dialog.removePreziTitle",
  31. null,
  32. "dialog.removePreziMsg",
  33. null,
  34. false,
  35. "dialog.Remove",
  36. function(e,v,m,f) {
  37. if(v) {
  38. APP.xmpp.removePreziFromPresence();
  39. }
  40. }
  41. );
  42. }
  43. else if (preziPlayer != null) {
  44. messageHandler.openTwoButtonDialog("dialog.sharePreziTitle",
  45. null, "dialog.sharePreziMsg",
  46. null,
  47. false,
  48. "dialog.Ok",
  49. function(e,v,m,f) {
  50. $.prompt.close();
  51. }
  52. );
  53. }
  54. else {
  55. var html = APP.translation.generateTranslationHTML(
  56. "dialog.sharePreziTitle");
  57. var cancelButton = APP.translation.generateTranslationHTML(
  58. "dialog.Cancel");
  59. var shareButton = APP.translation.generateTranslationHTML(
  60. "dialog.Share");
  61. var backButton = APP.translation.generateTranslationHTML(
  62. "dialog.Back");
  63. var buttons = [];
  64. var buttons1 = [];
  65. // Cancel button to both states
  66. buttons.push({title: cancelButton, value: false});
  67. buttons1.push({title: cancelButton, value: false});
  68. // Share button
  69. buttons.push({title: shareButton, value: true});
  70. // Back button
  71. buttons1.push({title: backButton, value: true});
  72. var linkError = APP.translation.generateTranslationHTML(
  73. "dialog.preziLinkError");
  74. var defaultUrl = APP.translation.translateString("defaultPreziLink",
  75. {url: "http://prezi.com/wz7vhjycl7e6/my-prezi"});
  76. var openPreziState = {
  77. state0: {
  78. html: '<h2>' + html + '</h2>' +
  79. '<input name="preziUrl" type="text" ' +
  80. 'data-i18n="[placeholder]defaultPreziLink" data-i18n-options=\'' +
  81. JSON.stringify({"url": "http://prezi.com/wz7vhjycl7e6/my-prezi"}) +
  82. '\' placeholder="' + defaultUrl + '" autofocus>',
  83. persistent: false,
  84. buttons: buttons,
  85. focus: ':input:first',
  86. defaultButton: 0,
  87. submit: function (e, v, m, f) {
  88. e.preventDefault();
  89. if(v)
  90. {
  91. var preziUrl = f.preziUrl;
  92. if (preziUrl)
  93. {
  94. var urlValue
  95. = encodeURI(UIUtil.escapeHtml(preziUrl));
  96. if (urlValue.indexOf('http://prezi.com/') != 0
  97. && urlValue.indexOf('https://prezi.com/') != 0)
  98. {
  99. $.prompt.goToState('state1');
  100. return false;
  101. }
  102. else {
  103. var presIdTmp = urlValue.substring(
  104. urlValue.indexOf("prezi.com/") + 10);
  105. if (!isAlphanumeric(presIdTmp)
  106. || presIdTmp.indexOf('/') < 2) {
  107. $.prompt.goToState('state1');
  108. return false;
  109. }
  110. else {
  111. APP.xmpp.addToPresence("prezi", urlValue);
  112. $.prompt.close();
  113. }
  114. }
  115. }
  116. }
  117. else
  118. $.prompt.close();
  119. }
  120. },
  121. state1: {
  122. html: '<h2>' + html + '</h2>' +
  123. linkError,
  124. persistent: false,
  125. buttons: buttons1,
  126. focus: ':input:first',
  127. defaultButton: 1,
  128. submit: function (e, v, m, f) {
  129. e.preventDefault();
  130. if (v === 0)
  131. $.prompt.close();
  132. else
  133. $.prompt.goToState('state0');
  134. }
  135. }
  136. };
  137. messageHandler.openDialogWithStates(openPreziState);
  138. }
  139. }
  140. };
  141. /**
  142. * A new presentation has been added.
  143. *
  144. * @param event the event indicating the add of a presentation
  145. * @param jid the jid from which the presentation was added
  146. * @param presUrl url of the presentation
  147. * @param currentSlide the current slide to which we should move
  148. */
  149. function presentationAdded(event, jid, presUrl, currentSlide) {
  150. console.log("presentation added", presUrl);
  151. var presId = getPresentationId(presUrl);
  152. var elementId = 'participant_'
  153. + Strophe.getResourceFromJid(jid)
  154. + '_' + presId;
  155. VideoLayout.addPreziContainer(elementId);
  156. VideoLayout.resizeThumbnails();
  157. var controlsEnabled = false;
  158. if (jid === APP.xmpp.myJid())
  159. controlsEnabled = true;
  160. setPresentationVisible(true);
  161. $('#largeVideoContainer').hover(
  162. function (event) {
  163. if (Prezi.isPresentationVisible()) {
  164. var reloadButtonRight = window.innerWidth
  165. - $('#presentation>iframe').offset().left
  166. - $('#presentation>iframe').width();
  167. $('#reloadPresentation').css({ right: reloadButtonRight,
  168. display:'inline-block'});
  169. }
  170. },
  171. function (event) {
  172. if (!Prezi.isPresentationVisible())
  173. $('#reloadPresentation').css({display:'none'});
  174. else {
  175. var e = event.toElement || event.relatedTarget;
  176. if (e && e.id != 'reloadPresentation' && e.id != 'header')
  177. $('#reloadPresentation').css({display:'none'});
  178. }
  179. });
  180. preziPlayer = new PreziPlayer(
  181. 'presentation',
  182. {preziId: presId,
  183. width: getPresentationWidth(),
  184. height: getPresentationHeihgt(),
  185. controls: controlsEnabled,
  186. debug: true
  187. });
  188. $('#presentation>iframe').attr('id', preziPlayer.options.preziId);
  189. preziPlayer.on(PreziPlayer.EVENT_STATUS, function(event) {
  190. console.log("prezi status", event.value);
  191. if (event.value == PreziPlayer.STATUS_CONTENT_READY) {
  192. if (jid != APP.xmpp.myJid())
  193. preziPlayer.flyToStep(currentSlide);
  194. }
  195. });
  196. preziPlayer.on(PreziPlayer.EVENT_CURRENT_STEP, function(event) {
  197. console.log("event value", event.value);
  198. APP.xmpp.addToPresence("preziSlide", event.value);
  199. });
  200. $("#" + elementId).css( 'background-image',
  201. 'url(../images/avatarprezi.png)');
  202. $("#" + elementId).click(
  203. function () {
  204. setPresentationVisible(true);
  205. }
  206. );
  207. };
  208. /**
  209. * A presentation has been removed.
  210. *
  211. * @param event the event indicating the remove of a presentation
  212. * @param jid the jid for which the presentation was removed
  213. * @param the url of the presentation
  214. */
  215. function presentationRemoved(event, jid, presUrl) {
  216. console.log('presentation removed', presUrl);
  217. var presId = getPresentationId(presUrl);
  218. setPresentationVisible(false);
  219. $('#participant_'
  220. + Strophe.getResourceFromJid(jid)
  221. + '_' + presId).remove();
  222. $('#presentation>iframe').remove();
  223. if (preziPlayer != null) {
  224. preziPlayer.destroy();
  225. preziPlayer = null;
  226. }
  227. };
  228. /**
  229. * Indicates if the given string is an alphanumeric string.
  230. * Note that some special characters are also allowed (-, _ , /, &, ?, =, ;) for the
  231. * purpose of checking URIs.
  232. */
  233. function isAlphanumeric(unsafeText) {
  234. var regex = /^[a-z0-9-_\/&\?=;]+$/i;
  235. return regex.test(unsafeText);
  236. }
  237. /**
  238. * Returns the presentation id from the given url.
  239. */
  240. function getPresentationId (presUrl) {
  241. var presIdTmp = presUrl.substring(presUrl.indexOf("prezi.com/") + 10);
  242. return presIdTmp.substring(0, presIdTmp.indexOf('/'));
  243. }
  244. /**
  245. * Returns the presentation width.
  246. */
  247. function getPresentationWidth() {
  248. var availableWidth = UIUtil.getAvailableVideoWidth();
  249. var availableHeight = getPresentationHeihgt();
  250. var aspectRatio = 16.0 / 9.0;
  251. if (availableHeight < availableWidth / aspectRatio) {
  252. availableWidth = Math.floor(availableHeight * aspectRatio);
  253. }
  254. return availableWidth;
  255. }
  256. /**
  257. * Returns the presentation height.
  258. */
  259. function getPresentationHeihgt() {
  260. var remoteVideos = $('#remoteVideos');
  261. return window.innerHeight - remoteVideos.outerHeight();
  262. }
  263. /**
  264. * Resizes the presentation iframe.
  265. */
  266. function resize() {
  267. if ($('#presentation>iframe')) {
  268. $('#presentation>iframe').width(getPresentationWidth());
  269. $('#presentation>iframe').height(getPresentationHeihgt());
  270. }
  271. }
  272. /**
  273. * Shows/hides a presentation.
  274. */
  275. function setPresentationVisible(visible) {
  276. var prezi = $('#presentation>iframe');
  277. if (visible) {
  278. // Trigger the video.selected event to indicate a change in the
  279. // large video.
  280. $(document).trigger("video.selected", [true]);
  281. $('#largeVideo').fadeOut(300);
  282. prezi.fadeIn(300, function() {
  283. prezi.css({opacity:'1'});
  284. ToolbarToggler.dockToolbar(true);
  285. VideoLayout.setLargeVideoVisible(false);
  286. });
  287. $('#activeSpeaker').css('visibility', 'hidden');
  288. }
  289. else {
  290. if (prezi.css('opacity') == '1') {
  291. prezi.fadeOut(300, function () {
  292. prezi.css({opacity:'0'});
  293. $('#reloadPresentation').css({display:'none'});
  294. $('#largeVideo').fadeIn(300, function() {
  295. VideoLayout.setLargeVideoVisible(true);
  296. ToolbarToggler.dockToolbar(false);
  297. });
  298. });
  299. }
  300. }
  301. }
  302. /**
  303. * Presentation has been removed.
  304. */
  305. $(document).bind('presentationremoved.muc', presentationRemoved);
  306. /**
  307. * Presentation has been added.
  308. */
  309. $(document).bind('presentationadded.muc', presentationAdded);
  310. /*
  311. * Indicates presentation slide change.
  312. */
  313. $(document).bind('gotoslide.muc', function (event, jid, presUrl, current) {
  314. if (preziPlayer && preziPlayer.getCurrentStep() != current) {
  315. preziPlayer.flyToStep(current);
  316. var animationStepsArray = preziPlayer.getAnimationCountOnSteps();
  317. for (var i = 0; i < parseInt(animationStepsArray[current]); i++) {
  318. preziPlayer.flyToStep(current, i);
  319. }
  320. }
  321. });
  322. /**
  323. * On video selected event.
  324. */
  325. $(document).bind('video.selected', function (event, isPresentation) {
  326. if (!isPresentation && $('#presentation>iframe')) {
  327. setPresentationVisible(false);
  328. }
  329. });
  330. $(window).resize(function () {
  331. resize();
  332. });
  333. module.exports = Prezi;