You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by Sam Ruby <ru...@apache.org> on 2015/12/19 22:29:18 UTC

[whimsy.git] [3/3] Commit f997a6b: move undoStack and selected to sessionStorage

Commit f997a6b78985d1b9f2f2d52a95b94993af17ba17:
    move undoStack and selected to sessionStorage


Branch: refs/heads/secmail
Author: Sam Ruby <ru...@intertwingly.net>
Committer: Sam Ruby <ru...@intertwingly.net>
Pusher: rubys <ru...@apache.org>

------------------------------------------------------------
www/secmail/views/app.js.rb                                  | + 
www/secmail/views/index.js.rb                                | ++++++++ -----
www/secmail/views/index.json.rb                              | +++ --
www/secmail/views/status.js.rb                               | ++++++++++ 
------------------------------------------------------------
95 changes: 75 additions, 20 deletions.
------------------------------------------------------------


diff --git a/www/secmail/views/app.js.rb b/www/secmail/views/app.js.rb
index 5906d9c..17bf47e 100644
--- a/www/secmail/views/app.js.rb
+++ b/www/secmail/views/app.js.rb
@@ -1,4 +1,5 @@
 require_relative 'http'
+require_relative 'status'
 
 require_relative 'index'
 require_relative 'parts'
diff --git a/www/secmail/views/index.js.rb b/www/secmail/views/index.js.rb
index a94e0da..dbd8d76 100644
--- a/www/secmail/views/index.js.rb
+++ b/www/secmail/views/index.js.rb
@@ -6,7 +6,6 @@ class Index < React
   def initialize
     @selected = nil
     @messages = []
-    @undoStack = []
     @checking = false
   end
 
@@ -48,7 +47,7 @@ def render
     _button.btn.btn_success 'check for new mail', onClick: self.refresh,
       disabled: @checking
 
-    unless @undoStack.empty?
+    unless Status.undoStack.empty?
       _button.btn.btn_info 'undo delete', onClick: self.undo
     end
   end
@@ -58,10 +57,12 @@ def componentWillMount()
     @nextmbox = @@mbox
   end
 
-  # on initial load, fetch latest mailbox and subscribe to keyboard events
+  # on initial load, fetch latest mailbox and subscribe to keyboard events,
+  # initialize selected item.
   def componentDidMount()
     self.fetch_month()
     window.onkeydown = self.keydown
+    @selected = Status.selected
   end
 
   # when content changes, ensure selected message is visible
@@ -90,31 +91,43 @@ def fetch_month()
       @messages = @messages.concat(*response.messages)
 
       # select oldest message
-      @selected = @messages.last.href
+      self.selectRow @messages.last unless @selected
     end
   end
 
-  # select
-  def selectRow(event)
-    @selected = event.currentTarget.querySelector('a').getAttribute('href')
+  # update @selected, given either a DOM event or a message
+  def selectRow(object)
+    if not object
+      href = nil
+    elsif object.respond_to? :currentTarget
+      href = object.currentTarget.querySelector('a').getAttribute('href')
+    elsif object.respond_to? :href
+      href = object.href
+    else
+      href = object
+    end
+
+    Status.selected = href
+    @selected = href
   end
 
   # navigate
   def nav(event)
-    @selected = event.currentTarget.querySelector('a').getAttribute('href')
+    self.selectRow(event)
     window.location.href = @selected
     window.getSelection().removeAllRanges()
     event.preventDefault()
   end
 
   def undo(event)
-    @selected = @undoStack.pop()
-    selected = @messages.find {|m| return m.href == @selected}
+    message = Status.popStack()
+    selected = @messages.find {|m| return m.href == message}
     if selected
+      self.selectRow selected
       selected.status = :deletePending
 
       # send request to server to remove delete status
-      HTTP.patch(@selected, status: nil) do
+      HTTP.patch(selected.href, status: nil) do
         delete selected.status
         self.forceUpdate()
       end
@@ -132,12 +145,12 @@ def refresh(event)
   def keydown(event)
     if event.keyCode == 38 # up
       index = @messages.findIndex {|m| return m.href == @selected}
-      @selected = @messages[index-1].href if index > 0
+      self.selectRow @messages[index-1] if index > 0
       event.preventDefault()
 
     elsif event.keyCode == 40 # down
       index = @messages.findIndex {|m| return m.href == @selected}
-      @selected = @messages[index+1].href if index < @messages.length-1
+      self.selectRow @messages[index+1] if index < @messages.length-1
       event.preventDefault()
 
     elsif event.keyCode == 13 or event.keyCode == 39 # enter/return or right
@@ -153,24 +166,24 @@ def keydown(event)
 
       # move selected pointer
       if index > 0
-        @selected = @messages[index-1].href
+        self.selectRow @messages[index-1]
       elsif index < @messages.length - 1
-        @selected = @messages[index+1].href
+        self.selectRow @messages[index+1]
       else
-        @selected = nil
+        self.selectRow nil
       end
 
       # send request to server to perform delete
       HTTP.delete(selected) do
         index = @messages.findIndex {|m| return m.href == selected}
         @messages[index].status = :deleted if index >= 0
-        @undoStack << selected
+        Status.pushDeleted selected
         self.forceUpdate()
       end
 
     elsif event.keyCode == 'Z'.ord
       if event.ctrlKey or event.metaKey
-        unless @undoStack.empty?
+        unless Status.undoStack.empty?
           self.undo()
           event.preventDefault()
         end
diff --git a/www/secmail/views/index.json.rb b/www/secmail/views/index.json.rb
index ed155c9..5482bb3 100644
--- a/www/secmail/views/index.json.rb
+++ b/www/secmail/views/index.json.rb
@@ -6,7 +6,7 @@
 if index
   # fetch a list of headers for all messages in the maibox with attachments
   headers = Mailbox.new(@mbox).headers.to_a.select do |id, message|
-    message[:attachments] and not message[:status] == :deleted
+    message[:attachments]
   end
 
   # extract relevant fields from the headers
@@ -15,7 +15,8 @@
       time: message[:time],
       href: "#{message[:source]}/#{id}/",
       from: message[:from],
-      subject: message['Subject']
+      subject: message['Subject'],
+      status: message[:status]
     }
   end
 
diff --git a/www/secmail/views/status.js.rb b/www/secmail/views/status.js.rb
new file mode 100644
index 0000000..aacacbd
--- /dev/null
+++ b/www/secmail/views/status.js.rb
@@ -0,0 +1,40 @@
+#
+# Encapsulate memory of selected item and delete stack
+#
+
+class Status
+  def self.secmail
+    return {} if not defined? sessionStorage
+    JSON.parse(sessionStorage.getItem('secmail') || '{}')
+  end
+
+  def self.selected
+    Status.secmail.selected
+  end
+
+  def self.selected=(value)
+    secmail = Status.secmail
+    secmail.selected=value
+    sessionStorage.setItem('secmail', JSON.stringify(secmail))
+  end
+
+  def self.undoStack
+    secmail = Status.secmail
+    return secmail.undoStack || []
+  end
+
+  def self.pushDeleted(value)
+    secmail = Status.secmail
+    secmail.undoStack ||= []
+    secmail.undoStack << value
+    sessionStorage.setItem('secmail', JSON.stringify(secmail))
+  end
+
+  def self.popStack()
+    secmail = Status.secmail
+    secmail.undoStack ||= []
+    item = secmail.undoStack.pop()
+    sessionStorage.setItem('secmail', JSON.stringify(secmail))
+    return item
+  end
+end