sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 5c814a1c057558f810e0edd5100990babccbb0d8
parent f5e1094d274e01698f700d99b07c002685b50ede
Author: Rich Lane <rlane@club.cc.cmu.edu>
Date:   Sun,  7 Mar 2010 13:17:46 -0800

Merge branch 'idle'

Diffstat:
M bin/sup | 4 ++++
M lib/sup.rb | 2 ++
A lib/sup/idle.rb | 42 ++++++++++++++++++++++++++++++++++++++++++
M lib/sup/modes/inbox-mode.rb | 4 ++++
M lib/sup/poll.rb | 15 +++++++++++++--
5 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/bin/sup b/bin/sup
@@ -236,6 +236,7 @@ EOS
 
   unless $opts[:no_threads]
     PollManager.start
+    IdleManager.start
     Index.start_lock_update_thread
   end
 
@@ -260,6 +261,8 @@ EOS
       next
     end
 
+    IdleManager.ping
+
     if c == 410
       ## this is ncurses's way of telling us it's detected a refresh.
       ## since we have our own sigwinch handler, we don't do anything.
@@ -368,6 +371,7 @@ rescue Exception => e
 ensure
   unless $opts[:no_threads]
     PollManager.stop if PollManager.instantiated?
+    IdleManager.stop if IdleManager.instantiated?
     Index.stop_lock_update_thread
   end
 
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -131,6 +131,7 @@ module Redwood
     Redwood::UndoManager.init
     Redwood::SourceManager.init
     Redwood::SearchManager.init Redwood::SEARCH_FN
+    Redwood::IdleManager.init
   end
 
   def finish
@@ -346,6 +347,7 @@ require "sup/modes/console-mode"
 require "sup/sent"
 require "sup/search"
 require "sup/modes/search-list-mode"
+require "sup/idle"
 
 $:.each do |base|
   d = File.join base, "sup/share/modes/"
diff --git a/lib/sup/idle.rb b/lib/sup/idle.rb
@@ -0,0 +1,42 @@
+require 'thread'
+
+module Redwood
+
+class IdleManager
+  include Singleton
+
+  IDLE_THRESHOLD = 60
+
+  def initialize
+    @no_activity_since = Time.now
+    @idle = false
+    @thread = nil
+  end
+
+  def ping
+    if @idle
+      UpdateManager.relay self, :unidle, Time.at(@no_activity_since)
+      @idle = false
+    end
+    @no_activity_since = Time.now
+  end
+
+  def start
+    @thread = Redwood::reporting_thread("checking for idleness") do
+      while true
+        sleep 1
+        if !@idle and Time.now.to_i - @no_activity_since.to_i >= IDLE_THRESHOLD
+          UpdateManager.relay self, :idle, Time.at(@no_activity_since)
+          @idle = true
+        end
+      end
+    end
+  end
+
+  def stop
+    @thread.kill if @thread
+    @thread = nil
+  end
+end
+
+end
diff --git a/lib/sup/modes/inbox-mode.rb b/lib/sup/modes/inbox-mode.rb
@@ -115,6 +115,10 @@ class InboxMode < ThreadIndexMode
     regen_text
   end
 
+  def handle_idle_update sender, idle_since
+    flush_index
+  end
+
   def status
     super + "    #{Index.size} messages in index"
   end
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
@@ -37,6 +37,9 @@ EOS
     @polling = false
     @poll_sources = nil
     @mode = nil
+    @should_clear_running_totals = false
+    clear_running_totals # defines @running_totals
+    UpdateManager.register self
   end
 
   def poll_with_sources
@@ -45,8 +48,12 @@ EOS
 
     BufferManager.flash "Polling for new messages..."
     num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
-    if num > 0
-      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
+    clear_running_totals if @should_clear_running_totals
+    @running_totals[:num] += num
+    @running_totals[:numi] += numi
+    @running_totals[:loaded_labels] += loaded_labels || []
+    if @running_totals[:num] > 0
+      BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
     else
       BufferManager.flash "No new messages." 
     end
@@ -183,6 +190,10 @@ EOS
     Index.add_message m
     UpdateManager.relay self, :added, m
   end
+
+  def handle_idle_update sender, idle_since; @should_clear_running_totals = false; end
+  def handle_unidle_update sender, idle_since; @should_clear_running_totals = true; clear_running_totals; end
+  def clear_running_totals; @running_totals = {:num => 0, :numi => 0, :loaded_labels => Set.new}; end
 end
 
 end