Parcourir la source

Speed up offline page by loading download statuses in a single transaction

Thibaut il y a 11 ans
Parent
commit
c2879a5e80

+ 20 - 0
assets/javascripts/app/db.coffee

@@ -103,6 +103,26 @@ class app.DB
       return
     return
 
+  versions: (docs, fn) ->
+    @db (db) ->
+      result = {}
+
+      unless db
+        result[doc.slug] = false for doc in docs
+        fn(result)
+        return
+
+      txn = db.transaction ['docs'], 'readonly'
+      txn.oncomplete = -> fn(result)
+      store = txn.objectStore('docs')
+
+      docs.forEach (doc) ->
+        req = store.get(doc.slug)
+        req.onsuccess = -> result[doc.slug] = req.result
+        req.onerror = -> result[doc.slug] = false
+        return
+      return
+
   load: (entry, onSuccess, onError) ->
     if @useIndexedDB and @_db isnt false
       onError = @loadWithXHR.bind(@, entry, onSuccess, onError)

+ 6 - 0
assets/javascripts/collections/docs.coffee

@@ -34,3 +34,9 @@ class app.collections.Docs extends app.Collection
   clearCache: ->
     doc.clearCache() for doc in @models
     return
+
+  getDownloadStatuses: (callback) ->
+    app.db.versions @models, (statuses) ->
+      for key, value of statuses
+        statuses[key] = downloaded: !!value, version: value
+      callback(statuses)

+ 6 - 9
assets/javascripts/templates/pages/offline_tmpl.coffee

@@ -1,16 +1,13 @@
-app.templates.offlinePage = ->
+app.templates.offlinePage = (docs) ->
   """ <h1 class="_lined-heading">Offline</h1>
-      <table class="_docs">
-        #{app.templates.render 'offlineDoc', app.docs.all()}
-      </table> """
+      <table class="_docs">#{docs}</table> """
 
-app.templates.offlineDoc = (doc) ->
-  """<tr data-slug="#{doc.slug}"></tr>"""
-
-app.templates.offlineDocContent = (doc, status) ->
-  html = """<th class="_icon-#{doc.slug}">#{doc.name}</th>"""
+app.templates.offlineDoc = (doc, status) ->
+  html = """<tr data-slug="#{doc.slug}">"""
+  html += """<th class="_icon-#{doc.slug}">#{doc.name}</th>"""
   html += if status.downloaded
     """<td><a data-del>Delete</a></td>"""
   else
     """<td><a data-dl>Download</a></td>"""
+  html += """</tr>"""
   html

+ 12 - 16
assets/javascripts/views/content/offline_page.coffee

@@ -4,32 +4,26 @@ class app.views.OfflinePage extends app.View
   @events:
     click: 'onClick'
 
-  @elements:
-    list: '_._docs'
-
   deactivate: ->
     if super
       @empty()
     return
 
   render: ->
-    @html @tmpl('offlinePage')
-    @refreshElements()
-    app.docs.each(@renderDoc)
+    app.docs.getDownloadStatuses (statuses) =>
+      html = ''
+      html += @renderDoc(doc, statuses[doc.slug]) for doc in app.docs.all()
+      @html @tmpl('offlinePage', html)
+      return
     return
 
-  renderDoc: (doc) =>
-    doc.getDownloadStatus (status) =>
-      html = app.templates.render('offlineDocContent', doc, status)
-      el = @docEl(doc)
-      el.className = ''
-      el.innerHTML = html
-    return
+  renderDoc: (doc, status) ->
+    app.templates.render('offlineDoc', doc, status)
 
   getTitle: ->
     'Offline'
 
-  getDoc: (el) ->
+  docByEl: (el) ->
     el = el.parentNode until slug = el.getAttribute('data-slug')
     app.docs.findBy('slug', slug)
 
@@ -48,16 +42,18 @@ class app.views.OfflinePage extends app.View
 
     if action
       $.stopEvent(event)
-      doc = @getDoc(event.target)
+      doc = @docByEl(event.target)
       doc[action](@onDownloadSuccess.bind(@, doc), @onDownloadError.bind(@, doc))
       @docEl(doc).classList.add("#{action}ing")
     return
 
   onDownloadSuccess: (doc) ->
-    @renderDoc(doc)
+    doc.getDownloadStatus (status) =>
+      @docEl(doc).outerHTML = @renderDoc(doc, status)
     return
 
   onDownloadError: (doc) ->
     el = @docEl(doc)
     el.className = ''
     el.classList.add('error')
+    return