SiteList.coffee 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. class SiteList extends Class
  2. constructor: ->
  3. @item_list = new ItemList(Site, "address")
  4. @sites = @item_list.items
  5. @sites_byaddress = @item_list.items_bykey
  6. @inactive_demo_sites = null
  7. @loaded = false
  8. @on_loaded = new Promise()
  9. @schedule_reorder = false
  10. @merged_db = {}
  11. @filtering = ""
  12. setInterval(@reorderTimer, 10000)
  13. @limit = 100
  14. @should_animate = false
  15. Page.on_settings.then =>
  16. Page.on_server_info.then =>
  17. @update()
  18. Page.cmd "channelJoinAllsite", {"channel": "siteChanged"}
  19. reorderTimer: =>
  20. if not @schedule_reorder
  21. return
  22. # Don't reorder if user if over site list or any of the sites are updating
  23. if not document.querySelector('.left:hover') and not document.querySelector(".working") and not Page.mode == "Files"
  24. @reorder()
  25. @schedule_reorder = false
  26. sortRows: (rows) =>
  27. if Page.settings.sites_orderby == "modified"
  28. rows.sort (a, b) ->
  29. return b.row.settings.modified - a.row.settings.modified
  30. else if Page.settings.sites_orderby == "addtime"
  31. rows.sort (a, b) ->
  32. return b.row.settings.added - a.row.settings.added
  33. else if Page.settings.sites_orderby == "size"
  34. rows.sort (a, b) ->
  35. return b.row.settings.size - a.row.settings.size
  36. else
  37. rows.sort (a, b) ->
  38. return Math.max(b.row.peers, b.row.settings.peers) - Math.max(a.row.peers, a.row.settings.peers)
  39. return rows
  40. reorder: =>
  41. @sortRows(@item_list.items)
  42. Page.projector.scheduleRender()
  43. update: ->
  44. if Page.server_info.rev >= 3660
  45. args = {connecting_sites: true}
  46. else
  47. args = {}
  48. Page.cmd "siteList", args, (site_rows) =>
  49. favorite_sites = Page.settings.favorite_sites
  50. @item_list.sync(site_rows)
  51. @sortRows(@item_list.items)
  52. if @inactive_demo_sites == null
  53. @updateInactiveDemoSites()
  54. Page.projector.scheduleRender()
  55. @loaded = true
  56. @log "loaded"
  57. @on_loaded.resolve()
  58. @
  59. updateInactiveDemoSites: ->
  60. demo_site_rows = [
  61. {address: "1TaLkFrMwvbNsooF4ioKAY9EuxTBTjipT", demo: true, content: {title: "ZeroTalk", domain: "Talk.ZeroNetwork.bit"}, settings: {}}
  62. {address: "1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8", demo: true, content: {title: "ZeroBlog", domain: "Blog.ZeroNetwork.bit"}, settings: {}}
  63. {address: "1MaiL5gfBM1cyb4a8e3iiL8L5gXmoAJu27", demo: true, content: {title: "ZeroMail", domain: "Mail.ZeroNetwork.bit"}, settings: {}}
  64. {address: "1uPLoaDwKzP6MCGoVzw48r4pxawRBdmQc", demo: true, content: {title: "ZeroUp"}, settings: {}}
  65. {address: "1Gif7PqWTzVWDQ42Mo7np3zXmGAo3DXc7h", demo: true, content: {title: "GIF Time"}, settings: {}}
  66. {address: "1SiTEs2D3rCBxeMoLHXei2UYqFcxctdwB", demo: true, content: {title: "More @ ZeroSites", domain: "Sites.ZeroNetwork.bit"}, settings: {}}
  67. ]
  68. if Page.server_info.rev >= 1400
  69. demo_site_rows.push {address: "1MeFqFfFFGQfa1J3gJyYYUvb5Lksczq7nH", demo: true, content: {title: "ZeroMe", domain: "Me.ZeroNetwork.bit"}, settings: {}}
  70. @inactive_demo_sites = []
  71. for site_row in demo_site_rows
  72. if @filtering and site.row.content.title.toLowerCase().indexOf(@filtering.toLowerCase()) == -1
  73. continue
  74. if not @sites_byaddress[site_row.address]
  75. @inactive_demo_sites.push(new Site(site_row))
  76. renderMergedSites: =>
  77. merged_db = {}
  78. for site in @sites_merged
  79. if not site.row.content.merged_type
  80. continue
  81. merged_db[site.row.content.merged_type] ?= []
  82. merged_db[site.row.content.merged_type].push site
  83. back = []
  84. for merged_type, merged_sites of merged_db
  85. back.push @renderSection(".merged.merged-#{merged_type}", "Merged: #{merged_type}", merged_sites),
  86. return back
  87. handleFilterInput: (e) =>
  88. @filtering = e.target.value
  89. handleFilterKeyup: (e) =>
  90. if e.keyCode == 27 # Esc
  91. e.target.value = ""
  92. @handleFilterInput(e)
  93. return false
  94. handleFilterClear: (e) =>
  95. e.target.value = ""
  96. @handleFilterInput(e)
  97. return false
  98. handleSiteListMoreClick: (e) =>
  99. @limit += 1000
  100. Page.projector.scheduleRender()
  101. return false
  102. handleSectionClick: (e) =>
  103. @should_animate = true
  104. class_name = e.currentTarget.getAttribute("class_name")
  105. if Page.settings.sites_section_hide[class_name]
  106. delete Page.settings.sites_section_hide[class_name]
  107. else
  108. Page.settings.sites_section_hide[class_name] = true
  109. Page.saveSettings()
  110. Page.projector.scheduleRender()
  111. return false
  112. renderSection: (class_name, title, items, limit=null) =>
  113. if items.length == 0
  114. return null
  115. classes = {"hidden": Page.settings.sites_section_hide[class_name]}
  116. if limit and items.length > limit
  117. items_limited = items[0..limit]
  118. else
  119. items_limited = items
  120. return [
  121. h("h2.SiteSection.section#{class_name}", {classes: classes},
  122. h("a.section-title", { href: "#Show", onclick: @handleSectionClick, class_name: class_name }, [
  123. title,
  124. h("span.hide-title", "[Show #{items.length} sites]")
  125. ])
  126. ),
  127. if not classes.hidden
  128. h("div.SiteList#{class_name}", {classes: classes, exitAnimation: Animation.slideUp, enterAnimation: Animation.slideDown, animate_disable: !@should_animate},
  129. [
  130. [ items_limited.map (item) -> item.render() ],
  131. if limit and items.length > limit
  132. h("a.site-list-more", {href: "#Show+more+connected+sites", onclick: @handleSiteListMoreClick}, "Show more")
  133. ]
  134. )
  135. ]
  136. render: =>
  137. if not @loaded
  138. return h("div#SiteList")
  139. @sites_needaction = []
  140. @sites_favorited = []
  141. @sites_owned = []
  142. @sites_recent = []
  143. @sites_connected = []
  144. @sites_connecting = []
  145. @sites_merged = []
  146. num_found = 0
  147. for site in @sites
  148. if @filtering
  149. filter_base = site.row.content.title + site.row.content.merged_type + site.row.address
  150. if filter_base.toLowerCase().indexOf(@filtering.toLowerCase()) == -1
  151. continue
  152. if site.row.settings.size * 1.2 > site.row.size_limit * 1024 * 1024
  153. site.row.need_limit = site.row.size_limit * 2
  154. @sites_needaction.push site
  155. else if site.favorite
  156. @sites_favorited.push site
  157. else if site.row.content.merged_type
  158. @sites_merged.push site
  159. else if site.row.settings?.own
  160. @sites_owned.push site
  161. else if site.row.settings?.downloaded > Time.timestamp() - 60 * 60 * 24
  162. @sites_recent.push site
  163. else if site.row.content.title
  164. @sites_connected.push site
  165. else
  166. @sites_connecting.push site
  167. num_found += 1
  168. h("div#SiteList", [
  169. if @sites.length > 10
  170. h("input.site-filter", {placeholder: "Filter: Site name", spellcheck: false, oninput: @handleFilterInput, onkeyup: @handleFilterKeyup, value: @filtering})
  171. if @filtering
  172. [
  173. h("span.filter-num", {updateAnimation: Animation.show, enterAnimation: Animation.show, exitAnimation: Animation.hide}, "(found #{num_found} of #{@sites.length} sites)")
  174. h("a.filter-clear", {href: "#clear", onclick: @handleFilterClear}, "\u00D7")
  175. ]
  176. @renderSection(".recent", "Recently downloaded:", @sites_recent),
  177. @renderSection(".needaction", "Running out of size limit:", @sites_needaction),
  178. @renderSection(".favorited", "Favorited sites:", @sites_favorited),
  179. @renderSection(".owned", "Owned sites:", @sites_owned),
  180. @renderSection(".connecting", "Connecting sites:", @sites_connecting),
  181. @renderSection(".connected", "Connected sites:", @sites_connected, @limit),
  182. @renderMergedSites()
  183. if @inactive_demo_sites != null and @inactive_demo_sites.length > 0
  184. @renderSection(".more", "More sites:", @inactive_demo_sites)
  185. ])
  186. onSiteInfo: (site_info) =>
  187. @item_list.items_bykey[site_info.address]?.setRow(site_info)
  188. @schedule_reorder = true
  189. Page.projector.scheduleRender()
  190. window.SiteList = SiteList