ZeroHello.coffee 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. window.h = maquette.h
  2. class ZeroHello extends ZeroFrame
  3. init: ->
  4. @params = {}
  5. @site_info = null
  6. @server_info = null
  7. @announcer_info = null
  8. @announcer_stats = null
  9. @address = null
  10. @on_site_info = new Promise()
  11. @on_server_info = new Promise()
  12. @on_settings = new Promise()
  13. @on_loaded = new Promise()
  14. @settings = null
  15. @server_errors = []
  16. @latest_version = "0.7.1"
  17. @latest_rev = 3616
  18. @mode = "Sites"
  19. @change_timer = null
  20. document.body.id = "Body#{@mode}"
  21. addRenderer: (node, renderer) ->
  22. @projector.replace(node, renderer)
  23. @renderers.push(renderer)
  24. detachRenderers: ->
  25. for renderer in @renderers
  26. @projector.detach(renderer)
  27. @renderers = []
  28. setProjectorMode: (mode) ->
  29. @log "setProjectorMode", mode
  30. if @mode == mode
  31. return
  32. @detachRenderers()
  33. if mode == "Files"
  34. @addRenderer($("#PageFiles"), @page_files.render)
  35. @page_files.need_update = true
  36. else if mode == "Stats"
  37. @addRenderer($("#PageStats"), @page_stats.render)
  38. @page_stats.need_update = true
  39. else
  40. mode = "Sites"
  41. @addRenderer($("#FeedList"), @feed_list.render)
  42. @addRenderer($("#SiteList"), @site_list.render)
  43. @mode = mode
  44. setTimeout ( ->
  45. # Delayed to avoid loosing anmation because of dom re-creation
  46. document.body.id = "Body#{mode}"
  47. if @change_timer
  48. clearInterval @change_timer
  49. document.body.classList.add("changing")
  50. @change_timer = setTimeout ( ->
  51. document.body.classList.remove("changing")
  52. ), 800
  53. ), 60
  54. createProjector: ->
  55. @projector = maquette.createProjector() # Dummy, will set later
  56. @projectors = {}
  57. @renderers = []
  58. @site_list = new SiteList()
  59. @feed_list = new FeedList()
  60. @page_files = new PageFiles()
  61. @page_stats = new PageStats()
  62. @head = new Head()
  63. @dashboard = new Dashboard()
  64. @mute_list = new MuteList()
  65. @trigger = new Trigger()
  66. if base.href.indexOf("?") == -1
  67. @route("")
  68. else
  69. url = base.href.replace(/.*?\?/, "")
  70. @route(url)
  71. @history_state["url"] = url
  72. @loadSettings()
  73. @on_site_info.then =>
  74. @projector.replace($("#Head"), @head.render)
  75. @projector.replace($("#Dashboard"), @dashboard.render)
  76. @projector.merge($("#Trigger"), @trigger.render)
  77. @setProjectorMode(@mode)
  78. # Update every minute to keep time since fields up-to date
  79. setInterval ( ->
  80. Page.projector.scheduleRender()
  81. ), 60*1000
  82. # Route site urls
  83. route: (query) ->
  84. @params = Text.parseQuery(query)
  85. @log "Route", @params
  86. @setProjectorMode(@params.url)
  87. if @mode == "Stats"
  88. @page_stats.need_update = true
  89. else if @mode == "Files"
  90. @page_files.need_update = true
  91. @projector.scheduleRender()
  92. # Add/remove/change parameter to current site url
  93. createUrl: (key, val) ->
  94. params = JSON.parse(JSON.stringify(@params)) # Clone
  95. if typeof key == "Object"
  96. vals = key
  97. for key, val of keys
  98. params[key] = val
  99. else
  100. params[key] = val
  101. return "?"+Text.encodeQuery(params)
  102. setUrl: (url, mode="replace") ->
  103. url = url.replace(/.*?\?/, "")
  104. @log "setUrl", @history_state["url"], "->", url
  105. if @history_state["url"] == url
  106. return false
  107. @history_state["url"] = url
  108. if mode == "replace"
  109. @cmd "wrapperReplaceState", [@history_state, "", url]
  110. else
  111. @cmd "wrapperPushState", [@history_state, "", url]
  112. @route url
  113. return false
  114. handleLinkClick: (e) =>
  115. if e.which == 2
  116. # Middle click dont do anything
  117. return true
  118. else
  119. @log "save scrollTop", window.pageYOffset
  120. @history_state["scrollTop"] = window.pageYOffset
  121. @cmd "wrapperReplaceState", [@history_state, null]
  122. window.scroll(window.pageXOffset, 0)
  123. @history_state["scrollTop"] = 0
  124. @setUrl e.currentTarget.search
  125. return false
  126. loadSettings: ->
  127. @on_site_info.then =>
  128. @cmd "userGetSettings", [], (res) =>
  129. if not res or res.error
  130. @loadLocalStorage()
  131. else
  132. @settings = res
  133. @settings.sites_orderby ?= "peers"
  134. @settings.sites_section_hide ?= {}
  135. @settings.favorite_sites ?= {}
  136. @settings.siteblocks_ignore ?= {}
  137. @settings.date_feed_visit ?= 1
  138. @feed_list.date_feed_visit = @settings.date_feed_visit
  139. @on_settings.resolve(@settings)
  140. loadLocalStorage: ->
  141. @cmd "wrapperGetLocalStorage", [], (@settings) =>
  142. @log "Loaded localstorage"
  143. @settings ?= {}
  144. @settings.sites_orderby ?= "peers"
  145. @settings.favorite_sites ?= {}
  146. @on_settings.resolve(@settings)
  147. saveSettings: (cb) ->
  148. if @settings
  149. if Page.server_info.rev > 2140
  150. @cmd "userSetSettings", [@settings], (res) =>
  151. if cb then cb(res)
  152. else
  153. @cmd "wrapperSetLocalStorage", @settings, (res) =>
  154. if cb then cb(res)
  155. onOpenWebsocket: (e) =>
  156. @reloadServerInfo()
  157. @reloadServerErrors()
  158. @reloadSiteInfo()
  159. reloadSiteInfo: =>
  160. @cmd "siteInfo", {}, (site_info) =>
  161. @address = site_info.address
  162. @setSiteInfo(site_info)
  163. reloadServerInfo: (cb) =>
  164. @cmd "serverInfo", {}, (server_info) =>
  165. @setServerInfo(server_info)
  166. cb?(server_info)
  167. reloadServerErrors: (cb) =>
  168. @on_server_info.then =>
  169. if @server_info.multiuser and not @server_info.multiuser_admin
  170. return cb?(false)
  171. @cmd "serverErrors", {}, (server_errors) =>
  172. @setServerErrors(server_errors)
  173. cb?(server_errors)
  174. reloadAnnouncerInfo: (cb) =>
  175. @cmd "announcerInfo", {}, (announcer_info) =>
  176. @setAnnouncerInfo(announcer_info)
  177. cb?()
  178. reloadAnnouncerStats: (cb) =>
  179. @cmd "announcerStats", {}, (announcer_stats) =>
  180. @announcer_stats = announcer_stats
  181. Page.projector.scheduleRender()
  182. cb?()
  183. # Parse incoming requests from UiWebsocket server
  184. onRequest: (cmd, params) ->
  185. if cmd == "setSiteInfo" # Site updated
  186. @setSiteInfo(params)
  187. else if cmd == "setServerInfo"
  188. @setServerInfo(params)
  189. else if cmd == "setAnnouncerInfo"
  190. @setAnnouncerInfo(params)
  191. else
  192. @log "Unknown command", params
  193. setSiteInfo: (site_info) ->
  194. if site_info.address == @address
  195. @site_info = site_info
  196. if @server_info?.rev > 3530
  197. @reloadAnnouncerStats()
  198. else if @server_info?.rev > 3460
  199. @reloadAnnouncerInfo()
  200. @site_list.onSiteInfo(site_info)
  201. @feed_list.onSiteInfo(site_info)
  202. @page_files.onSiteInfo(site_info)
  203. @on_site_info.resolve()
  204. setServerInfo: (server_info) ->
  205. @server_info = server_info
  206. if parseFloat(Page.server_info.version.replace(/\./g, "0")) < 700
  207. @latest_version = "0.6.5"
  208. @projector.scheduleRender()
  209. if server_info.event?[0] == "log_event"
  210. RateLimit 1000, =>
  211. @reloadServerErrors()
  212. @on_server_info.resolve()
  213. setServerErrors: (server_errors) ->
  214. @server_errors = []
  215. for [date_added, level, message] in server_errors
  216. @server_errors.push({
  217. title: [Time.since(date_added), " - ", level],
  218. descr: message,
  219. href: "#ZeroNet:Console:Error"
  220. })
  221. @projector.scheduleRender()
  222. setAnnouncerInfo: (announcer_info) ->
  223. @announcer_info = announcer_info.stats
  224. @projector.scheduleRender()
  225. # Simple return false to avoid link clicks
  226. returnFalse: ->
  227. return false
  228. updateZeronet: ->
  229. if @server_info.updatesite # Python3 version: Go to site
  230. window.top.location = Text.getSiteUrl(@server_info.updatesite)
  231. else
  232. Page.cmd "wrapperNotification", ["info", "Updating to latest version...<br>Please restart ZeroNet manually if it does not come back in the next few minutes.", 8000]
  233. Page.cmd "serverUpdate"
  234. window.Page = new ZeroHello()
  235. window.Page.createProjector()