aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrianBlade <n.gelbertz@gmail.com>2015-04-03 00:06:37 +0200
committerBrianBlade <n.gelbertz@gmail.com>2015-04-08 23:29:52 +0200
commitdace8ba3d3815599a70d5e369cd3b1f418842a0e (patch)
treeede7f178510894aabb227e03fccc9f25bc85c682
parent59ea143147548ee15211d7c334076a158757c85f (diff)
Enable end-conversation by swipe gesture
Add EnhancedListView library de.timroes.android:EnhancedListView:0.3.4 to enable swipe-out for ListViews Re-enable selectableItemBackground Dont end selectedConversation on swipe Call mConversationFragment.reinit() instead. Add separate undo string for swipe MUC. Add blacklistedConversation for undo swipe Update title_undo_swipe_* strings Fix undo(), rename blacklistedConversation Fix discardUndo(); re-init selectedConversation maintain scroll position after undo clear notification when dismissing a conversation modified / simplified maintain scroll position code simplify handling of selectedConversation change undo_muc string, remove notifyDataSetChanged()
-rw-r--r--build.gradle1
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java1
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java103
-rw-r--r--src/main/res/layout-w960dp/fragment_conversations_overview.xml2
-rw-r--r--src/main/res/layout/conversation_list_row.xml138
-rw-r--r--src/main/res/layout/fragment_conversations_overview.xml2
-rw-r--r--src/main/res/values-de/strings.xml2
-rw-r--r--src/main/res/values-v21/dimens.xml4
-rw-r--r--src/main/res/values/strings.xml3
9 files changed, 185 insertions, 71 deletions
diff --git a/build.gradle b/build.gradle
index 8f7bb914a..cdbb5a98a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -34,6 +34,7 @@ dependencies {
compile 'com.google.zxing:core:3.1.0'
compile 'com.google.zxing:android-integration:3.1.0'
compile 'de.measite.minidns:minidns:0.1.3'
+ compile 'de.timroes.android:EnhancedListView:0.3.4'
}
android {
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index ca182867a..9badbbd80 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1129,6 +1129,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
public void archiveConversation(Conversation conversation) {
+ getNotificationService().clear(conversation);
conversation.setStatus(Conversation.STATUS_ARCHIVED);
conversation.setNextEncryption(-1);
synchronized (this.conversations) {
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 82afda073..29308cc56 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -22,12 +22,12 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
-import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.Toast;
import net.java.otr4j.session.SessionStatus;
+import de.timroes.android.listview.EnhancedListView;
import java.util.ArrayList;
import java.util.List;
@@ -76,8 +76,9 @@ public class ConversationActivity extends XmppActivity
private View mContentView;
private List<Conversation> conversationList = new ArrayList<>();
+ private Conversation swipedConversation = null;
private Conversation mSelectedConversation = null;
- private ListView listView;
+ private EnhancedListView listView;
private ConversationFragment mConversationFragment;
private ArrayAdapter<Conversation> listAdapter;
@@ -156,7 +157,7 @@ public class ConversationActivity extends XmppActivity
transaction.replace(R.id.selected_conversation, this.mConversationFragment, "conversation");
transaction.commit();
- listView = (ListView) findViewById(R.id.list);
+ listView = (EnhancedListView) findViewById(R.id.list);
this.listAdapter = new ConversationAdapter(this, conversationList);
listView.setAdapter(this.listAdapter);
@@ -178,6 +179,73 @@ public class ConversationActivity extends XmppActivity
openConversation();
}
});
+
+ listView.setDismissCallback(new EnhancedListView.OnDismissCallback() {
+
+ @Override
+ public EnhancedListView.Undoable onDismiss(final EnhancedListView enhancedListView, final int position) {
+
+ final int index = listView.getFirstVisiblePosition();
+ View v = listView.getChildAt(0);
+ final int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
+
+ swipedConversation = listAdapter.getItem(position);
+ listAdapter.remove(swipedConversation);
+ swipedConversation.markRead();
+ xmppConnectionService.getNotificationService().clear(swipedConversation);
+
+ final boolean formerlySelected = (getSelectedConversation() == swipedConversation);
+ if (position == 0 && listAdapter.getCount() == 0) {
+ endConversation(swipedConversation, false, true);
+ return null;
+ } else if (formerlySelected) {
+ setSelectedConversation(listAdapter.getItem(0));
+ ConversationActivity.this.mConversationFragment
+ .reInit(getSelectedConversation());
+ }
+
+ return new EnhancedListView.Undoable() {
+
+ @Override
+ public void undo() {
+ listAdapter.insert(swipedConversation, position);
+ if (formerlySelected) {
+ setSelectedConversation(swipedConversation);
+ ConversationActivity.this.mConversationFragment
+ .reInit(getSelectedConversation());
+ }
+ swipedConversation = null;
+ listView.setSelectionFromTop(index + (listView.getChildCount() < position ? 1 : 0), top);
+ }
+
+ @Override
+ public void discard() {
+ if (!swipedConversation.isRead()
+ && swipedConversation.getMode() == Conversation.MODE_SINGLE) {
+ swipedConversation = null;
+ return;
+ }
+ endConversation(swipedConversation, false, false);
+ swipedConversation = null;
+ }
+
+ @Override
+ public String getTitle() {
+ if (swipedConversation.getMode() == Conversation.MODE_MULTI) {
+ return getResources().getString(R.string.title_undo_swipe_out_muc);
+ } else {
+ return getResources().getString(R.string.title_undo_swipe_out_conversation);
+ }
+ }
+ };
+ }
+ });
+ listView.enableSwipeToDismiss();
+ listView.setSwipingLayout(R.id.swipeable_item);
+ listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP);
+ listView.setUndoHideDelay(3000);
+ listView.setRequireTouchBeforeDismiss(false);
+
mContentView = findViewById(R.id.content_view_spl);
if (mContentView == null) {
mContentView = findViewById(R.id.content_view_ll);
@@ -204,6 +272,7 @@ public class ConversationActivity extends XmppActivity
@Override
public void onPanelClosed(View arg0) {
+ listView.discardUndo();
openConversation();
}
@@ -485,13 +554,21 @@ public class ConversationActivity extends XmppActivity
}
public void endConversation(Conversation conversation) {
- showConversationsOverview();
+ endConversation(conversation, true, true);
+ }
+
+ public void endConversation(Conversation conversation, boolean showOverview, boolean reinit) {
+ if (showOverview) {
+ showConversationsOverview();
+ }
xmppConnectionService.archiveConversation(conversation);
- if (conversationList.size() > 0) {
- setSelectedConversation(conversationList.get(0));
- this.mConversationFragment.reInit(getSelectedConversation());
- } else {
- setSelectedConversation(null);
+ if (reinit) {
+ if (conversationList.size() > 0) {
+ setSelectedConversation(conversationList.get(0));
+ this.mConversationFragment.reInit(getSelectedConversation());
+ } else {
+ setSelectedConversation(null);
+ }
}
}
@@ -744,6 +821,7 @@ public class ConversationActivity extends XmppActivity
@Override
public void onPause() {
+ listView.discardUndo();
super.onPause();
this.mActivityPaused = true;
if (this.xmppConnectionServiceBound) {
@@ -1013,6 +1091,13 @@ public class ConversationActivity extends XmppActivity
public void updateConversationList() {
xmppConnectionService
.populateWithOrderedConversations(conversationList);
+ if (swipedConversation != null) {
+ if (swipedConversation.isRead()) {
+ conversationList.remove(swipedConversation);
+ } else {
+ listView.discardUndo();
+ }
+ }
listAdapter.notifyDataSetChanged();
}
diff --git a/src/main/res/layout-w960dp/fragment_conversations_overview.xml b/src/main/res/layout-w960dp/fragment_conversations_overview.xml
index 2744f38ef..50039c03a 100644
--- a/src/main/res/layout-w960dp/fragment_conversations_overview.xml
+++ b/src/main/res/layout-w960dp/fragment_conversations_overview.xml
@@ -12,7 +12,7 @@
android:background="@color/primarybackground"
android:orientation="vertical" >
- <ListView
+ <de.timroes.android.listview.EnhancedListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
diff --git a/src/main/res/layout/conversation_list_row.xml b/src/main/res/layout/conversation_list_row.xml
index 21147b4a0..de04780fe 100644
--- a/src/main/res/layout/conversation_list_row.xml
+++ b/src/main/res/layout/conversation_list_row.xml
@@ -1,68 +1,86 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:padding="8dp" >
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:descendantFocusability="blocksDescendants">
- <ImageView
- android:id="@+id/conversation_image"
- android:layout_width="56dp"
- android:layout_height="56dp"
- android:layout_alignParentLeft="true"
- android:scaleType="centerCrop" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@color/divider"/>
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@+id/conversation_image"
- android:paddingLeft="8dp" >
+ <FrameLayout
+ android:id="@+id/swipeable_item"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@color/primarybackground">
- <TextView
- android:id="@+id/conversation_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@+id/conversation_lastwrapper"
- android:layout_toLeftOf="@+id/conversation_lastupdate"
- android:singleLine="true"
- android:textColor="@color/primarytext"
- android:textSize="?attr/TextSizeHeadline"
- android:typeface="sans" />
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:background="?android:selectableItemBackground"
+ android:orientation="horizontal"
+ android:padding="8dp" >
- <LinearLayout
- android:id="@+id/conversation_lastwrapper"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/conversation_name"
- android:orientation="vertical"
- android:paddingTop="3dp" >
+ <ImageView
+ android:id="@+id/conversation_image"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_alignParentLeft="true"
+ android:scaleType="centerCrop" />
- <TextView
- android:id="@+id/conversation_lastmsg"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:scrollHorizontally="false"
- android:singleLine="true"
- android:textColor="@color/primarytext"
- android:textSize="?attr/TextSizeBody" />
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toRightOf="@+id/conversation_image"
+ android:paddingLeft="8dp" >
- <ImageView
- android:id="@+id/conversation_lastimage"
- android:layout_width="fill_parent"
- android:layout_height="36dp"
- android:background="@color/primarytext"
- android:scaleType="centerCrop" />
- </LinearLayout>
+ <TextView
+ android:id="@+id/conversation_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@+id/conversation_lastwrapper"
+ android:layout_toLeftOf="@+id/conversation_lastupdate"
+ android:singleLine="true"
+ android:textColor="@color/primarytext"
+ android:textSize="?attr/TextSizeHeadline"
+ android:typeface="sans" />
- <TextView
- android:id="@+id/conversation_lastupdate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/conversation_name"
- android:layout_alignParentRight="true"
- android:gravity="right"
- android:textColor="@color/secondarytext"
- android:textSize="?attr/TextSizeInfo" />
- </RelativeLayout>
+ <LinearLayout
+ android:id="@+id/conversation_lastwrapper"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/conversation_name"
+ android:orientation="vertical"
+ android:paddingTop="3dp" >
-</RelativeLayout> \ No newline at end of file
+ <TextView
+ android:id="@+id/conversation_lastmsg"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:scrollHorizontally="false"
+ android:singleLine="true"
+ android:textColor="@color/primarytext"
+ android:textSize="?attr/TextSizeBody" />
+
+ <ImageView
+ android:id="@+id/conversation_lastimage"
+ android:layout_width="fill_parent"
+ android:layout_height="36dp"
+ android:background="@color/primarytext"
+ android:scaleType="centerCrop" />
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/conversation_lastupdate"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@+id/conversation_name"
+ android:layout_alignParentRight="true"
+ android:gravity="right"
+ android:textColor="@color/secondarytext"
+ android:textSize="?attr/TextSizeInfo" />
+ </RelativeLayout>
+ </RelativeLayout>
+ </FrameLayout>
+</FrameLayout> \ No newline at end of file
diff --git a/src/main/res/layout/fragment_conversations_overview.xml b/src/main/res/layout/fragment_conversations_overview.xml
index 695700288..24c653ae6 100644
--- a/src/main/res/layout/fragment_conversations_overview.xml
+++ b/src/main/res/layout/fragment_conversations_overview.xml
@@ -10,7 +10,7 @@
android:background="@color/primarybackground"
android:orientation="vertical" >
- <ListView
+ <de.timroes.android.listview.EnhancedListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index b8266182c..3f6f471bc 100644
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -427,6 +427,8 @@
<string name="no_application_found_to_display_location">Keine App für die Standort-Anzeige gefunden</string>
<string name="location">Standort</string>
<string name="received_location">Standort empfangen</string>
+ <string name="title_undo_swipe_out_conversation">Unterhaltung beendet</string>
+ <string name="title_undo_swipe_out_muc">Konferenz verlassen</string>
<plurals name="select_contact">
<item quantity="one">%d Kontakt ausgewählt</item>
<item quantity="other">%d Kontakte ausgewählt</item>
diff --git a/src/main/res/values-v21/dimens.xml b/src/main/res/values-v21/dimens.xml
new file mode 100644
index 000000000..8bc8f3f7b
--- /dev/null
+++ b/src/main/res/values-v21/dimens.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <dimen name="elv_undo_bottom_offset">63dp</dimen> <!-- 48dp + 15dp -->
+</resources> \ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index af56c0146..50e9d9e43 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -296,6 +296,7 @@
\n\nhttps://developer.android.com/tools/support-library\n(Apache License, Version 2.0)
\n\nhttps://github.com/zxing/zxing\n(Apache License, Version 2.0)
\n\nhttps://github.com/google/material-design-icons\n(CC BY 4.0)
+ \n\nhttps://github.com/timroes/EnhancedListView\n(Apache License, Version 2.0)
</string>
<string name="title_pref_quiet_hours">Quiet Hours</string>
<string name="title_pref_quiet_hours_start_time">Start time</string>
@@ -454,6 +455,8 @@
<string name="no_application_found_to_display_location">No application found to display location</string>
<string name="location">Location</string>
<string name="received_location">Received location</string>
+ <string name="title_undo_swipe_out_conversation">Conversation closed</string>
+ <string name="title_undo_swipe_out_muc">Left conference</string>
<plurals name="select_contact">
<item quantity="one">Select %d contact</item>
<item quantity="other">Select %d contacts</item>