use ctrl+arrow up to correct last message. fixes #3806

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Conversation.java    | 15 
src/main/java/eu/siacs/conversations/entities/Message.java         |  7 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java  |  9 
src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java | 16 
4 files changed, 41 insertions(+), 6 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Conversation.java 🔗

@@ -186,6 +186,21 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
         return null;
     }
 
+    public Message getLastEditableMessage() {
+        synchronized (this.messages) {
+            for(final Message message : Lists.reverse(this.messages)) {
+                if (message.isEditable()) {
+                    if (message.isGeoUri() || message.getType() != Message.TYPE_TEXT) {
+                        return null;
+                    }
+                    return message;
+                }
+            }
+        }
+        return null;
+    }
+
+
     public Message findUnsentMessageWithUuid(String uuid) {
         synchronized (this.messages) {
             for (final Message message : this.messages) {

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -15,7 +15,6 @@ import java.lang.ref.WeakReference;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -613,15 +612,15 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
 	public boolean isLastCorrectableMessage() {
 		Message next = next();
 		while (next != null) {
-			if (next.isCorrectable()) {
+			if (next.isEditable()) {
 				return false;
 			}
 			next = next.next();
 		}
-		return isCorrectable();
+		return isEditable();
 	}
 
-	private boolean isCorrectable() {
+	public boolean isEditable() {
 		return getStatus() != STATUS_RECEIVED && !isCarbon();
 	}
 

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -2748,6 +2748,15 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
         return p.getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send));
     }
 
+    public boolean onArrowUpCtrlPressed() {
+        final Message lastEditableMessage = conversation == null ? null : conversation.getLastEditableMessage();
+        if (lastEditableMessage != null) {
+            correctMessage(lastEditableMessage);
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void onTypingStarted() {
         final XmppConnectionService service = activity == null ? null : activity.xmppConnectionService;

src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java 🔗

@@ -49,6 +49,7 @@ import android.support.v7.app.ActionBar;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.widget.Toolbar;
 import android.util.Log;
+import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.Toast;
@@ -493,8 +494,19 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
     }
 
     @Override
-    public void onSaveInstanceState(Bundle savedInstanceState) {
-        Intent pendingIntent = pendingViewIntent.peek();
+    public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
+        if (keyCode == KeyEvent.KEYCODE_DPAD_UP && keyEvent.isCtrlPressed()) {
+            final ConversationFragment conversationFragment = ConversationFragment.get(this);
+            if (conversationFragment != null && conversationFragment.onArrowUpCtrlPressed()) {
+                return true;
+            }
+        }
+        return super.onKeyDown(keyCode, keyEvent);
+    }
+
+    @Override
+    public void onSaveInstanceState(final Bundle savedInstanceState) {
+        final Intent pendingIntent = pendingViewIntent.peek();
         savedInstanceState.putParcelable("intent", pendingIntent != null ? pendingIntent : getIntent());
         super.onSaveInstanceState(savedInstanceState);
     }