At the moment, the reconnect feature is somewhat glitchy, popping up
multiple reconnect prompts even if a reconnection succeeds, and
occasionally causing crashes.  A successful reconnection results in the
conversation history being cleared, which is an annoying outcome when
connected over an unreliable network.

This patch does the following:

* Keep track of whether a reconnect dialog is active, to prevent
  multiple dialogs from opening.
* Introduce a new field to the Server object, mayReconnect, which is
  used to keep track of whether a reconnection should be attempted in
  the event of a disconnection.  It's set to "true" when we connect to a
  server, and "false" if the user asks for a disconnection.
* Prevent the clearing of active conversations and conversation history
  on disconnect, unless the user specifically asked for the disconnect.
* Keep the IRCService running even when no servers are connected, unless
  the user has disconnected from all servers herself.  This is needed
  for reliable auto-reconnects (see next patch), but has the side effect
  of keeping conversation history around even if the activity isn't open
  when a disconnect happens.
---
 .../org/yaaic/activity/ConversationActivity.java   |   25 ++++++++++++--------
 .../src/org/yaaic/activity/ServersActivity.java    |    4 ++-
 application/src/org/yaaic/irc/IRCConnection.java   |    4 +-
 application/src/org/yaaic/irc/IRCService.java      |    2 +-
 application/src/org/yaaic/model/Server.java        |   17 +++++++++++++
 5 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/application/src/org/yaaic/activity/ConversationActivity.java 
b/application/src/org/yaaic/activity/ConversationActivity.java
index 542dfbb..2c60d33 100644
--- a/application/src/org/yaaic/activity/ConversationActivity.java
+++ b/application/src/org/yaaic/activity/ConversationActivity.java
@@ -121,6 +121,8 @@ public class ConversationActivity extends Activity 
implements ServiceConnection,
 
     private int historySize;
 
+    private boolean reconnectDialogActive = false;
+
     OnKeyListener inputKeyListener = new OnKeyListener() {
         /**
          * On key pressed (input line)
@@ -392,6 +394,8 @@ public class ConversationActivity extends Activity 
implements ServiceConnection,
         if (server.getStatus() == Status.PRE_CONNECTING && 
getIntent().hasExtra("connect")) {
             server.setStatus(Status.CONNECTING);
             binder.connect(server);
+        } else {
+            onStatusUpdate();
         }
     }
 
@@ -441,6 +445,7 @@ public class ConversationActivity extends Activity 
implements ServiceConnection,
         switch (item.getItemId()) {
             case R.id.disconnect:
                 server.setStatus(Status.DISCONNECTED);
+                server.setMayReconnect(false);
                 binder.getService().getConnection(serverId).quitServer();
                 server.clearConversations();
                 setResult(RESULT_OK);
@@ -604,10 +609,6 @@ public class ConversationActivity extends Activity 
implements ServiceConnection,
             input.setEnabled(false);
 
             if (server.getStatus() == Status.CONNECTING) {
-                deckAdapter.clearConversations();
-                Conversation serverInfo = 
server.getConversation(ServerInfo.DEFAULT_NAME);
-                serverInfo.setHistorySize(historySize);
-                deckAdapter.addItem(serverInfo);
                 return;
             }
 
@@ -616,27 +617,31 @@ public class ConversationActivity extends Activity 
implements ServiceConnection,
                 return;
             }
 
-            if (!binder.getService().getSettings().isReconnectEnabled()) {
+            if (!binder.getService().getSettings().isReconnectEnabled() && 
!reconnectDialogActive) {
+                reconnectDialogActive = true;
                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
                 
builder.setMessage(getResources().getString(R.string.reconnect_after_disconnect,
 server.getTitle()))
                 .setCancelable(false)
                 .setPositiveButton("Yes", new 
DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int id) {
+                        if (!server.isDisconnected()) {
+                            reconnectDialogActive = false;
+                            return;
+                        }
                         
binder.getService().getConnection(server.getId()).setAutojoinChannels(
                             server.getCurrentChannelNames()
                         );
-                        server.clearConversations();
-                        deckAdapter.clearConversations();
-                        Conversation serverInfo = 
server.getConversation(ServerInfo.DEFAULT_NAME);
-                        serverInfo.setHistorySize(historySize);
-                        deckAdapter.addItem(serverInfo);
+                        server.setStatus(Status.CONNECTING);
                         binder.connect(server);
+                        reconnectDialogActive = false;
                     }
                 })
                 .setNegativeButton(getString(R.string.negative_button), new 
DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int id) {
+                        server.setMayReconnect(false);
+                        reconnectDialogActive = false;
                         dialog.cancel();
                     }
                 });
diff --git a/application/src/org/yaaic/activity/ServersActivity.java 
b/application/src/org/yaaic/activity/ServersActivity.java
index cfcf38d..aa3e83d 100644
--- a/application/src/org/yaaic/activity/ServersActivity.java
+++ b/application/src/org/yaaic/activity/ServersActivity.java
@@ -175,7 +175,7 @@ public class ServersActivity extends ListActivity 
implements ServiceConnection,
 
         Intent intent = new Intent(this, ConversationActivity.class);
 
-        if (server.getStatus() == Status.DISCONNECTED) {
+        if (server.getStatus() == Status.DISCONNECTED && 
!server.mayReconnect()) {
             server.setStatus(Status.PRE_CONNECTING);
             intent.putExtra("connect", true);
         }
@@ -220,6 +220,7 @@ public class ServersActivity extends ListActivity 
implements ServiceConnection,
                     case 1: // Disconnect
                         server.clearConversations();
                         server.setStatus(Status.DISCONNECTED);
+                        server.setMayReconnect(false);
                         
binder.getService().getConnection(server.getId()).quitServer();
                         break;
                     case 2: // Edit
@@ -292,6 +293,7 @@ public class ServersActivity extends ListActivity 
implements ServiceConnection,
                 for (Server server : mServers) {
                     if (binder.getService().hasConnection(server.getId())) {
                         server.setStatus(Status.DISCONNECTED);
+                        server.setMayReconnect(false);
                         
binder.getService().getConnection(server.getId()).quitServer();
                     }
                 }
diff --git a/application/src/org/yaaic/irc/IRCConnection.java 
b/application/src/org/yaaic/irc/IRCConnection.java
index 1330f73..e5940f9 100644
--- a/application/src/org/yaaic/irc/IRCConnection.java
+++ b/application/src/org/yaaic/irc/IRCConnection.java
@@ -140,6 +140,7 @@ public class IRCConnection extends PircBot
     public void onConnect()
     {
         server.setStatus(Status.CONNECTED);
+        server.setMayReconnect(true);
 
         service.sendBroadcast(
             Broadcast.createServerIntent(Broadcast.SERVER_UPDATE, 
server.getId())
@@ -372,7 +373,7 @@ public class IRCConnection extends PircBot
     @Override
     protected void onJoin(String target, String sender, String login, String 
hostname)
     {
-        if (sender.equalsIgnoreCase(getNick())) {
+        if (sender.equalsIgnoreCase(getNick()) && 
server.getConversation(target) == null) {
             // We joined a new channel
             Conversation conversation = new Channel(target);
             
conversation.setHistorySize(service.getSettings().getHistorySize());
@@ -1132,7 +1133,6 @@ public class IRCConnection extends PircBot
         if (service.getSettings().isReconnectEnabled() && server.getStatus() 
!= Status.DISCONNECTED) {
             setAutojoinChannels(server.getCurrentChannelNames());
 
-            server.clearConversations();
             server.setStatus(Status.CONNECTING);
             service.connect(server);
         } else {
diff --git a/application/src/org/yaaic/irc/IRCService.java 
b/application/src/org/yaaic/irc/IRCService.java
index 00e0d36..ea0892c 100644
--- a/application/src/org/yaaic/irc/IRCService.java
+++ b/application/src/org/yaaic/irc/IRCService.java
@@ -485,7 +485,7 @@ public class IRCService extends Service
 
         for (int i = 0; i < mSize; i++) {
             server = mServers.get(i);
-            if (server.isDisconnected()) {
+            if (server.isDisconnected() && !server.mayReconnect()) {
                 int serverId = server.getId();
                 synchronized(this) {
                     IRCConnection connection = connections.get(serverId);
diff --git a/application/src/org/yaaic/model/Server.java 
b/application/src/org/yaaic/model/Server.java
index 156ed0c..58eca98 100644
--- a/application/src/org/yaaic/model/Server.java
+++ b/application/src/org/yaaic/model/Server.java
@@ -51,6 +51,7 @@ public class Server
     private int status = Status.DISCONNECTED;
     private String selected = "";
     private boolean isForeground = false;
+    private boolean mayReconnect = false;
 
     /**
      * Create a new server object
@@ -443,4 +444,20 @@ public class Server
     {
         this.isForeground = isForeground;
     }
+
+    /**
+     * Get whether a reconnect may be attempted if we're disconnected.
+     */
+    public boolean mayReconnect()
+    {
+        return mayReconnect;
+    }
+
+    /**
+     * Set whether a reconnect may be attempted if we're disconnected.
+     */
+    public void setMayReconnect(boolean mayReconnect)
+    {
+        this.mayReconnect = mayReconnect;
+    }
 }
-- 
1.7.2.5

Reply via email to