Sidebar.coffee 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. class Sidebar extends Class
  2. constructor: (@wrapper) ->
  3. @tag = null
  4. @container = null
  5. @opened = false
  6. @width = 410
  7. @internals = new Internals(@)
  8. @fixbutton = $(".fixbutton")
  9. @fixbutton_addx = 0
  10. @fixbutton_addy = 0
  11. @fixbutton_initx = 0
  12. @fixbutton_inity = 15
  13. @fixbutton_targetx = 0
  14. @move_lock = null
  15. @page_width = $(window).width()
  16. @page_height = $(window).height()
  17. @frame = $("#inner-iframe")
  18. @initFixbutton()
  19. @dragStarted = 0
  20. @globe = null
  21. @preload_html = null
  22. @original_set_site_info = @wrapper.setSiteInfo # We going to override this, save the original
  23. # Start in opened state for debugging
  24. if false
  25. @startDrag()
  26. @moved()
  27. @fixbutton_targetx = @fixbutton_initx - @width
  28. @stopDrag()
  29. initFixbutton: ->
  30. # Detect dragging
  31. @fixbutton.on "mousedown touchstart", (e) =>
  32. if e.button > 0 # Right or middle click
  33. return
  34. e.preventDefault()
  35. # Disable previous listeners
  36. @fixbutton.off "click touchend touchcancel"
  37. @fixbutton.off "mousemove touchmove"
  38. # Make sure its not a click
  39. @dragStarted = (+ new Date)
  40. @fixbutton.one "mousemove touchmove", (e) =>
  41. mousex = e.pageX
  42. mousey = e.pageY
  43. if not mousex
  44. mousex = e.originalEvent.touches[0].pageX
  45. mousey = e.originalEvent.touches[0].pageY
  46. @fixbutton_addx = @fixbutton.offset().left - mousex
  47. @fixbutton_addy = @fixbutton.offset().top - mousey
  48. @startDrag()
  49. @fixbutton.parent().on "click touchend touchcancel", (e) =>
  50. if (+ new Date) - @dragStarted < 100
  51. window.top.location = @fixbutton.find(".fixbutton-bg").attr("href")
  52. @stopDrag()
  53. @resized()
  54. $(window).on "resize", @resized
  55. resized: =>
  56. @page_width = $(window).width()
  57. @page_height = $(window).height()
  58. @fixbutton_initx = @page_width - 75 # Initial x position
  59. if @opened
  60. @fixbutton.css
  61. left: @fixbutton_initx - @width
  62. else
  63. @fixbutton.css
  64. left: @fixbutton_initx
  65. # Start dragging the fixbutton
  66. startDrag: ->
  67. @move_lock = "x" # Temporary until internals not finished
  68. @log "startDrag"
  69. @fixbutton_targetx = @fixbutton_initx # Fallback x position
  70. @fixbutton.addClass("dragging")
  71. # Fullscreen drag bg to capture mouse events over iframe
  72. $("<div class='drag-bg'></div>").appendTo(document.body)
  73. # IE position wrap fix
  74. if navigator.userAgent.indexOf('MSIE') != -1 or navigator.appVersion.indexOf('Trident/') > 0
  75. @fixbutton.css("pointer-events", "none")
  76. # Don't go to homepage
  77. @fixbutton.one "click", (e) =>
  78. @stopDrag()
  79. @fixbutton.removeClass("dragging")
  80. moved_x = Math.abs(@fixbutton.offset().left - @fixbutton_initx)
  81. moved_y = Math.abs(@fixbutton.offset().top - @fixbutton_inity)
  82. if moved_x > 5 or moved_y > 10
  83. # If moved more than some pixel the button then don't go to homepage
  84. e.preventDefault()
  85. # Animate drag
  86. @fixbutton.parents().on "mousemove touchmove", @animDrag
  87. @fixbutton.parents().on "mousemove touchmove" ,@waitMove
  88. # Stop dragging listener
  89. @fixbutton.parents().one "mouseup touchend touchcancel", (e) =>
  90. e.preventDefault()
  91. @stopDrag()
  92. # Wait for moving the fixbutton
  93. waitMove: (e) =>
  94. document.body.style.perspective = "1000px"
  95. document.body.style.height = "100%"
  96. document.body.style.willChange = "perspective"
  97. document.documentElement.style.height = "100%"
  98. #$(document.body).css("backface-visibility", "hidden").css("perspective", "1000px").css("height", "900px")
  99. # $("iframe").css("backface-visibility", "hidden")
  100. moved_x = Math.abs(parseInt(@fixbutton[0].style.left) - @fixbutton_targetx)
  101. moved_y = Math.abs(parseInt(@fixbutton[0].style.top) - @fixbutton_targety)
  102. if moved_x > 5 and (+ new Date) - @dragStarted + moved_x > 50
  103. @moved("x")
  104. @fixbutton.stop().animate {"top": @fixbutton_inity}, 1000
  105. @fixbutton.parents().off "mousemove touchmove" ,@waitMove
  106. else if moved_y > 5 and (+ new Date) - @dragStarted + moved_y > 50
  107. @moved("y")
  108. @fixbutton.parents().off "mousemove touchmove" ,@waitMove
  109. moved: (direction) ->
  110. @log "Moved", direction
  111. @move_lock = direction
  112. if direction == "y"
  113. $(document.body).addClass("body-internals")
  114. return @internals.createHtmltag()
  115. @createHtmltag()
  116. $(document.body).addClass("body-sidebar")
  117. @container.on "mousedown touchend touchcancel", (e) =>
  118. if e.target != e.currentTarget
  119. return true
  120. @log "closing"
  121. if $(document.body).hasClass("body-sidebar")
  122. @close()
  123. return true
  124. $(window).off "resize"
  125. $(window).on "resize", =>
  126. $(document.body).css "height", $(window).height()
  127. @scrollable()
  128. @resized()
  129. # Override setsiteinfo to catch changes
  130. @wrapper.setSiteInfo = (site_info) =>
  131. @setSiteInfo(site_info)
  132. @original_set_site_info.apply(@wrapper, arguments)
  133. # Preload world.jpg
  134. img = new Image();
  135. img.src = "/uimedia/globe/world.jpg";
  136. setSiteInfo: (site_info) ->
  137. RateLimit 1500, =>
  138. @updateHtmlTag()
  139. RateLimit 30000, =>
  140. @displayGlobe()
  141. # Create the sidebar html tag
  142. createHtmltag: ->
  143. @when_loaded = $.Deferred()
  144. if not @container
  145. @container = $("""
  146. <div class="sidebar-container"><div class="sidebar scrollable"><div class="content-wrapper"><div class="content">
  147. </div></div></div></div>
  148. """)
  149. @container.appendTo(document.body)
  150. @tag = @container.find(".sidebar")
  151. @updateHtmlTag()
  152. @scrollable = window.initScrollable()
  153. updateHtmlTag: ->
  154. if @preload_html
  155. @setHtmlTag(@preload_html)
  156. @preload_html = null
  157. else
  158. @wrapper.ws.cmd "sidebarGetHtmlTag", {}, @setHtmlTag
  159. setHtmlTag: (res) =>
  160. if @tag.find(".content").children().length == 0 # First update
  161. @log "Creating content"
  162. @container.addClass("loaded")
  163. morphdom(@tag.find(".content")[0], '<div class="content">'+res+'</div>')
  164. # @scrollable()
  165. @when_loaded.resolve()
  166. else # Not first update, patch the html to keep unchanged dom elements
  167. morphdom @tag.find(".content")[0], '<div class="content">'+res+'</div>', {
  168. onBeforeMorphEl: (from_el, to_el) -> # Ignore globe loaded state
  169. if from_el.className == "globe" or from_el.className.indexOf("noupdate") >= 0
  170. return false
  171. else
  172. return true
  173. }
  174. # Save and forgot privatekey for site signing
  175. @tag.find("#privatekey-add").off("click, touchend").on "click touchend", (e) =>
  176. @wrapper.displayPrompt "Enter your private key:", "password", "Save", "", (privatekey) =>
  177. @wrapper.ws.cmd "userSetSitePrivatekey", [privatekey], (res) =>
  178. @wrapper.notifications.add "privatekey", "done", "Private key saved for site signing", 5000
  179. return false
  180. @tag.find("#privatekey-forgot").off("click, touchend").on "click touchend", (e) =>
  181. @wrapper.displayConfirm "Remove saved private key for this site?", "Forgot", (res) =>
  182. if not res
  183. return false
  184. @wrapper.ws.cmd "userSetSitePrivatekey", [""], (res) =>
  185. @wrapper.notifications.add "privatekey", "done", "Saved private key removed", 5000
  186. return false
  187. animDrag: (e) =>
  188. mousex = e.pageX
  189. mousey = e.pageY
  190. if not mousex and e.originalEvent.touches
  191. mousex = e.originalEvent.touches[0].pageX
  192. mousey = e.originalEvent.touches[0].pageY
  193. overdrag = @fixbutton_initx - @width - mousex
  194. if overdrag > 0 # Overdragged
  195. overdrag_percent = 1 + overdrag/300
  196. mousex = (mousex + (@fixbutton_initx-@width)*overdrag_percent)/(1+overdrag_percent)
  197. targetx = @fixbutton_initx - mousex - @fixbutton_addx
  198. targety = @fixbutton_inity - mousey - @fixbutton_addy
  199. if @move_lock == "x"
  200. targety = @fixbutton_inity
  201. else if @move_lock == "y"
  202. targetx = @fixbutton_initx
  203. if not @move_lock or @move_lock == "x"
  204. @fixbutton[0].style.left = (mousex + @fixbutton_addx) + "px"
  205. if @tag
  206. @tag[0].style.transform = "translateX(#{0 - targetx}px)"
  207. if not @move_lock or @move_lock == "y"
  208. @fixbutton[0].style.top = (mousey + @fixbutton_addy) + "px"
  209. if @internals.tag
  210. @internals.tag[0].style.transform = "translateY(#{0 - targety}px)"
  211. #if @move_lock == "x"
  212. # @fixbutton[0].style.left = "#{@fixbutton_targetx} px"
  213. #@fixbutton[0].style.top = "#{@fixbutton_inity}px"
  214. #if @move_lock == "y"
  215. # @fixbutton[0].style.top = "#{@fixbutton_targety} px"
  216. # Check if opened
  217. if (not @opened and targetx > @width/3) or (@opened and targetx > @width*0.9)
  218. @fixbutton_targetx = @fixbutton_initx - @width # Make it opened
  219. else
  220. @fixbutton_targetx = @fixbutton_initx
  221. if (not @internals.opened and 0 - targety > @page_height/10) or (@internals.opened and 0 - targety > @page_height*0.95)
  222. @fixbutton_targety = @page_height - @fixbutton_inity - 50
  223. else
  224. @fixbutton_targety = @fixbutton_inity
  225. # Stop dragging the fixbutton
  226. stopDrag: ->
  227. @fixbutton.parents().off "mousemove touchmove"
  228. @fixbutton.off "mousemove touchmove"
  229. @fixbutton.css("pointer-events", "")
  230. $(".drag-bg").remove()
  231. if not @fixbutton.hasClass("dragging")
  232. return
  233. @fixbutton.removeClass("dragging")
  234. # Move back to initial position
  235. if @fixbutton_targetx != @fixbutton.offset().left
  236. # Animate fixbutton
  237. if @move_lock == "y"
  238. top = @fixbutton_targety
  239. left = @fixbutton_initx
  240. if @move_lock == "x"
  241. top = @fixbutton_inity
  242. left = @fixbutton_targetx
  243. @fixbutton.stop().animate {"left": left, "top": top}, 500, "easeOutBack", =>
  244. # Switch back to auto align
  245. if @fixbutton_targetx == @fixbutton_initx # Closed
  246. @fixbutton.css("left", "auto")
  247. else # Opened
  248. @fixbutton.css("left", left)
  249. $(".fixbutton-bg").trigger "mouseout" # Switch fixbutton back to normal status
  250. @stopDragX()
  251. @internals.stopDragY()
  252. @move_lock = null
  253. stopDragX: ->
  254. # Animate sidebar and iframe
  255. if @fixbutton_targetx == @fixbutton_initx or @move_lock == "y"
  256. # Closed
  257. targetx = 0
  258. @opened = false
  259. else
  260. # Opened
  261. targetx = @width
  262. if @opened
  263. @onOpened()
  264. else
  265. @when_loaded.done =>
  266. @onOpened()
  267. @opened = true
  268. # Revent sidebar transitions
  269. if @tag
  270. @tag.css("transition", "0.4s ease-out")
  271. @tag.css("transform", "translateX(-#{targetx}px)").one transitionEnd, =>
  272. @tag.css("transition", "")
  273. if not @opened
  274. @container.remove()
  275. @container = null
  276. if @tag
  277. @tag.remove()
  278. @tag = null
  279. # Revert body transformations
  280. @log "stopdrag", "opened:", @opened
  281. if not @opened
  282. @onClosed()
  283. onOpened: ->
  284. @log "Opened"
  285. @scrollable()
  286. # Re-calculate height when site admin opened or closed
  287. @tag.find("#checkbox-owned, #checkbox-autodownloadoptional").off("click touchend").on "click touchend", =>
  288. setTimeout (=>
  289. @scrollable()
  290. ), 300
  291. # Site limit button
  292. @tag.find("#button-sitelimit").off("click touchend").on "click touchend", =>
  293. @wrapper.ws.cmd "siteSetLimit", $("#input-sitelimit").val(), (res) =>
  294. if res == "ok"
  295. @wrapper.notifications.add "done-sitelimit", "done", "Site storage limit modified!", 5000
  296. @updateHtmlTag()
  297. return false
  298. # Site autodownload limit button
  299. @tag.find("#button-autodownload_bigfile_size_limit").off("click touchend").on "click touchend", =>
  300. @wrapper.ws.cmd "siteSetAutodownloadBigfileLimit", $("#input-autodownload_bigfile_size_limit").val(), (res) =>
  301. if res == "ok"
  302. @wrapper.notifications.add "done-bigfilelimit", "done", "Site bigfile auto download limit modified!", 5000
  303. @updateHtmlTag()
  304. return false
  305. # Database reload
  306. @tag.find("#button-dbreload").off("click touchend").on "click touchend", =>
  307. @wrapper.ws.cmd "dbReload", [], =>
  308. @wrapper.notifications.add "done-dbreload", "done", "Database schema reloaded!", 5000
  309. @updateHtmlTag()
  310. return false
  311. # Database rebuild
  312. @tag.find("#button-dbrebuild").off("click touchend").on "click touchend", =>
  313. @wrapper.notifications.add "done-dbrebuild", "info", "Database rebuilding...."
  314. @wrapper.ws.cmd "dbRebuild", [], =>
  315. @wrapper.notifications.add "done-dbrebuild", "done", "Database rebuilt!", 5000
  316. @updateHtmlTag()
  317. return false
  318. # Update site
  319. @tag.find("#button-update").off("click touchend").on "click touchend", =>
  320. @tag.find("#button-update").addClass("loading")
  321. @wrapper.ws.cmd "siteUpdate", @wrapper.site_info.address, =>
  322. @wrapper.notifications.add "done-updated", "done", "Site updated!", 5000
  323. @tag.find("#button-update").removeClass("loading")
  324. return false
  325. # Pause site
  326. @tag.find("#button-pause").off("click touchend").on "click touchend", =>
  327. @tag.find("#button-pause").addClass("hidden")
  328. @wrapper.ws.cmd "sitePause", @wrapper.site_info.address
  329. return false
  330. # Resume site
  331. @tag.find("#button-resume").off("click touchend").on "click touchend", =>
  332. @tag.find("#button-resume").addClass("hidden")
  333. @wrapper.ws.cmd "siteResume", @wrapper.site_info.address
  334. return false
  335. # Delete site
  336. @tag.find("#button-delete").off("click touchend").on "click touchend", =>
  337. @wrapper.displayConfirm "Are you sure?", ["Delete this site", "Blacklist"], (confirmed) =>
  338. if confirmed == 1
  339. @tag.find("#button-delete").addClass("loading")
  340. @wrapper.ws.cmd "siteDelete", @wrapper.site_info.address, ->
  341. document.location = $(".fixbutton-bg").attr("href")
  342. else if confirmed == 2
  343. @wrapper.displayPrompt "Blacklist this site", "text", "Delete and Blacklist", "Reason", (reason) =>
  344. @tag.find("#button-delete").addClass("loading")
  345. @wrapper.ws.cmd "siteblockAdd", [@wrapper.site_info.address, reason]
  346. @wrapper.ws.cmd "siteDelete", @wrapper.site_info.address, ->
  347. document.location = $(".fixbutton-bg").attr("href")
  348. return false
  349. # Owned checkbox
  350. @tag.find("#checkbox-owned").off("click touchend").on "click touchend", =>
  351. @wrapper.ws.cmd "siteSetOwned", [@tag.find("#checkbox-owned").is(":checked")]
  352. # Owned checkbox
  353. @tag.find("#checkbox-autodownloadoptional").off("click touchend").on "click touchend", =>
  354. @wrapper.ws.cmd "siteSetAutodownloadoptional", [@tag.find("#checkbox-autodownloadoptional").is(":checked")]
  355. # Change identity button
  356. @tag.find("#button-identity").off("click touchend").on "click touchend", =>
  357. @wrapper.ws.cmd "certSelect"
  358. return false
  359. # Save settings
  360. @tag.find("#button-settings").off("click touchend").on "click touchend", =>
  361. @wrapper.ws.cmd "fileGet", "content.json", (res) =>
  362. data = JSON.parse(res)
  363. data["title"] = $("#settings-title").val()
  364. data["description"] = $("#settings-description").val()
  365. json_raw = unescape(encodeURIComponent(JSON.stringify(data, undefined, '\t')))
  366. @wrapper.ws.cmd "fileWrite", ["content.json", btoa(json_raw), true], (res) =>
  367. if res != "ok" # fileWrite failed
  368. @wrapper.notifications.add "file-write", "error", "File write error: #{res}"
  369. else
  370. @wrapper.notifications.add "file-write", "done", "Site settings saved!", 5000
  371. if @wrapper.site_info.privatekey
  372. @wrapper.ws.cmd "siteSign", {privatekey: "stored", inner_path: "content.json", update_changed_files: true}
  373. @updateHtmlTag()
  374. return false
  375. # Open site directory
  376. @tag.find("#link-directory").off("click touchend").on "click touchend", =>
  377. @wrapper.ws.cmd "serverShowdirectory", ["site", @wrapper.site_info.address]
  378. return false
  379. # Copy site with peers
  380. @tag.find("#link-copypeers").off("click touchend").on "click touchend", (e) =>
  381. copy_text = e.currentTarget.href
  382. handler = (e) =>
  383. e.clipboardData.setData('text/plain', copy_text)
  384. e.preventDefault()
  385. @wrapper.notifications.add "copy", "done", "Site address with peers copied to your clipboard", 5000
  386. document.removeEventListener('copy', handler, true)
  387. document.addEventListener('copy', handler, true)
  388. document.execCommand('copy')
  389. return false
  390. # Sign and publish content.json
  391. $(document).on "click touchend", =>
  392. @tag?.find("#button-sign-publish-menu").removeClass("visible")
  393. @tag?.find(".contents + .flex").removeClass("sign-publish-flex")
  394. @tag.find(".contents-content").off("click touchend").on "click touchend", (e) =>
  395. $("#input-contents").val(e.currentTarget.innerText);
  396. return false;
  397. menu = new Menu(@tag.find("#menu-sign-publish"))
  398. menu.elem.css("margin-top", "-130px") # Open upwards
  399. menu.addItem "Sign", =>
  400. inner_path = @tag.find("#input-contents").val()
  401. @wrapper.ws.cmd "fileRules", {inner_path: inner_path}, (res) =>
  402. if @wrapper.site_info.privatekey
  403. # Privatekey stored in users.json
  404. @wrapper.ws.cmd "siteSign", {privatekey: "stored", inner_path: inner_path, update_changed_files: true}, (res) =>
  405. if res == "ok"
  406. @wrapper.notifications.add "sign", "done", "#{inner_path} Signed!", 5000
  407. else if @wrapper.site_info.auth_address in res.signers
  408. # ZeroID or other ID provider
  409. @wrapper.ws.cmd "siteSign", {privatekey: null, inner_path: inner_path, update_changed_files: true}, (res) =>
  410. if res == "ok"
  411. @wrapper.notifications.add "sign", "done", "#{inner_path} Signed!", 5000
  412. else
  413. # Ask the user for privatekey
  414. @wrapper.displayPrompt "Enter your private key:", "password", "Sign", "", (privatekey) => # Prompt the private key
  415. @wrapper.ws.cmd "siteSign", {privatekey: privatekey, inner_path: inner_path, update_changed_files: true}, (res) =>
  416. if res == "ok"
  417. @wrapper.notifications.add "sign", "done", "#{inner_path} Signed!", 5000
  418. @tag.find(".contents + .flex").removeClass "active"
  419. menu.hide()
  420. menu.addItem "Publish", =>
  421. inner_path = @tag.find("#input-contents").val()
  422. @wrapper.ws.cmd "sitePublish", {"inner_path": inner_path, "sign": false}
  423. @tag.find(".contents + .flex").removeClass "active"
  424. menu.hide()
  425. @tag.find("#menu-sign-publish").off("click touchend").on "click touchend", =>
  426. if window.visible_menu == menu
  427. @tag.find(".contents + .flex").removeClass "active"
  428. menu.hide()
  429. else
  430. @tag.find(".contents + .flex").addClass "active"
  431. @tag.find(".content-wrapper").prop "scrollTop", 10000
  432. menu.show()
  433. return false
  434. $("body").on "click", =>
  435. if @tag
  436. @tag.find(".contents + .flex").removeClass "active"
  437. @tag.find("#button-sign-publish").off("click touchend").on "click touchend", =>
  438. inner_path = @tag.find("#input-contents").val()
  439. @wrapper.ws.cmd "fileRules", {inner_path: inner_path}, (res) =>
  440. if @wrapper.site_info.privatekey
  441. # Privatekey stored in users.json
  442. @wrapper.ws.cmd "sitePublish", {privatekey: "stored", inner_path: inner_path, sign: true, update_changed_files: true}, (res) =>
  443. if res == "ok"
  444. @wrapper.notifications.add "sign", "done", "#{inner_path} Signed and published!", 5000
  445. else if @wrapper.site_info.auth_address in res.signers
  446. # ZeroID or other ID provider
  447. @wrapper.ws.cmd "sitePublish", {privatekey: null, inner_path: inner_path, sign: true, update_changed_files: true}, (res) =>
  448. if res == "ok"
  449. @wrapper.notifications.add "sign", "done", "#{inner_path} Signed and published!", 5000
  450. else
  451. # Ask the user for privatekey
  452. @wrapper.displayPrompt "Enter your private key:", "password", "Sign", "", (privatekey) => # Prompt the private key
  453. @wrapper.ws.cmd "sitePublish", {privatekey: privatekey, inner_path: inner_path, sign: true, update_changed_files: true}, (res) =>
  454. if res == "ok"
  455. @wrapper.notifications.add "sign", "done", "#{inner_path} Signed and published!", 5000
  456. return false
  457. # Close
  458. @tag.find(".close").off("click touchend").on "click touchend", (e) =>
  459. @close()
  460. return false
  461. @loadGlobe()
  462. close: ->
  463. @move_lock = "x"
  464. @startDrag()
  465. @stopDrag()
  466. onClosed: ->
  467. $(window).off "resize"
  468. $(window).on "resize", @resized
  469. $(document.body).css("transition", "0.6s ease-in-out").removeClass("body-sidebar").on transitionEnd, (e) =>
  470. if e.target == document.body and not $(document.body).hasClass("body-sidebar") and not $(document.body).hasClass("body-internals")
  471. $(document.body).css("height", "auto").css("perspective", "").css("will-change", "").css("transition", "").off transitionEnd
  472. @unloadGlobe()
  473. # We dont need site info anymore
  474. @wrapper.setSiteInfo = @original_set_site_info
  475. loadGlobe: =>
  476. console.log "loadGlobe", @tag.find(".globe")[0], @tag.find(".globe").hasClass("loading")
  477. if @tag.find(".globe").hasClass("loading")
  478. setTimeout (=>
  479. if typeof(DAT) == "undefined" # Globe script not loaded, do it first
  480. script_tag = $("<script>")
  481. script_tag.attr("nonce", @wrapper.script_nonce)
  482. script_tag.attr("src", "/uimedia/globe/all.js")
  483. script_tag.on("load", @displayGlobe)
  484. document.head.appendChild(script_tag[0])
  485. else
  486. @displayGlobe()
  487. ), 600
  488. displayGlobe: =>
  489. img = new Image();
  490. img.src = "/uimedia/globe/world.jpg";
  491. img.onload = =>
  492. @wrapper.ws.cmd "sidebarGetPeers", [], (globe_data) =>
  493. if @globe
  494. @globe.scene.remove(@globe.points)
  495. @globe.addData( globe_data, {format: 'magnitude', name: "hello", animated: false} )
  496. @globe.createPoints()
  497. @tag?.find(".globe").removeClass("loading")
  498. else if typeof(DAT) != "undefined"
  499. try
  500. @globe = new DAT.Globe( @tag.find(".globe")[0], {"imgDir": "/uimedia/globe/"} )
  501. @globe.addData( globe_data, {format: 'magnitude', name: "hello"} )
  502. @globe.createPoints()
  503. @globe.animate()
  504. catch e
  505. console.log "WebGL error", e
  506. @tag?.find(".globe").addClass("error").text("WebGL not supported")
  507. @tag?.find(".globe").removeClass("loading")
  508. unloadGlobe: =>
  509. if not @globe
  510. return false
  511. @globe.unload()
  512. @globe = null
  513. wrapper = window.wrapper
  514. setTimeout ( ->
  515. window.sidebar = new Sidebar(wrapper)
  516. ), 500
  517. window.transitionEnd = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend'