made swipe and select work
This commit is contained in:
parent
6bd0abcd8e
commit
354b182968
|
@ -2211,6 +2211,15 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Conversation getConversation(Activity activity) {
|
||||||
|
Fragment fragment = activity.getFragmentManager().findFragmentById(R.id.secondary_fragment);
|
||||||
|
if (fragment != null && fragment instanceof ConversationFragment) {
|
||||||
|
return ((ConversationFragment) fragment).getConversation();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Conversation getConversation() {
|
public Conversation getConversation() {
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,24 +53,38 @@ import eu.siacs.conversations.ui.service.EmojiService;
|
||||||
|
|
||||||
public class ConversationsMainActivity extends XmppActivity implements OnConversationSelected, OnConversationArchived, OnConversationsListItemUpdated, OnConversationRead {
|
public class ConversationsMainActivity extends XmppActivity implements OnConversationSelected, OnConversationArchived, OnConversationsListItemUpdated, OnConversationRead {
|
||||||
|
|
||||||
|
|
||||||
|
//secondary fragment (when holding the conversation, must be initialized before refreshing the overview fragment
|
||||||
|
private static final @IdRes int[] FRAGMENT_ID_NOTIFICATION_ORDER = {R.id.secondary_fragment, R.id.main_fragment};
|
||||||
|
|
||||||
private ActivityConversationsBinding binding;
|
private ActivityConversationsBinding binding;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void refreshUiReal() {
|
protected void refreshUiReal() {
|
||||||
|
for(@IdRes int id : FRAGMENT_ID_NOTIFICATION_ORDER) {
|
||||||
|
refreshFragment(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {
|
||||||
notifyFragment(R.id.main_fragment);
|
for(@IdRes int id : FRAGMENT_ID_NOTIFICATION_ORDER) {
|
||||||
notifyFragment(R.id.secondary_fragment);
|
notifyFragmentOfBackendConnected(id);
|
||||||
|
}
|
||||||
invalidateActionBarTitle();
|
invalidateActionBarTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyFragment(@IdRes int id) {
|
private void notifyFragmentOfBackendConnected(@IdRes int id) {
|
||||||
Fragment mainFragment = getFragmentManager().findFragmentById(id);
|
final Fragment fragment = getFragmentManager().findFragmentById(id);
|
||||||
if (mainFragment != null && mainFragment instanceof XmppFragment) {
|
if (fragment != null && fragment instanceof XmppFragment) {
|
||||||
((XmppFragment) mainFragment).onBackendConnected();
|
((XmppFragment) fragment).onBackendConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshFragment(@IdRes int id) {
|
||||||
|
final Fragment fragment = getFragmentManager().findFragmentById(id);
|
||||||
|
if (fragment != null && fragment instanceof XmppFragment) {
|
||||||
|
((XmppFragment) fragment).refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,14 +108,21 @@ public class ConversationsMainActivity extends XmppActivity implements OnConvers
|
||||||
public void onConversationSelected(Conversation conversation) {
|
public void onConversationSelected(Conversation conversation) {
|
||||||
Log.d(Config.LOGTAG, "selected " + conversation.getName());
|
Log.d(Config.LOGTAG, "selected " + conversation.getName());
|
||||||
ConversationFragment conversationFragment = (ConversationFragment) getFragmentManager().findFragmentById(R.id.secondary_fragment);
|
ConversationFragment conversationFragment = (ConversationFragment) getFragmentManager().findFragmentById(R.id.secondary_fragment);
|
||||||
|
final boolean mainNeedsRefresh;
|
||||||
if (conversationFragment == null) {
|
if (conversationFragment == null) {
|
||||||
|
mainNeedsRefresh = false;
|
||||||
conversationFragment = new ConversationFragment();
|
conversationFragment = new ConversationFragment();
|
||||||
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
|
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
|
||||||
fragmentTransaction.replace(R.id.main_fragment, conversationFragment);
|
fragmentTransaction.replace(R.id.main_fragment, conversationFragment);
|
||||||
fragmentTransaction.addToBackStack(null);
|
fragmentTransaction.addToBackStack(null);
|
||||||
fragmentTransaction.commit();
|
fragmentTransaction.commit();
|
||||||
|
} else {
|
||||||
|
mainNeedsRefresh = true;
|
||||||
}
|
}
|
||||||
conversationFragment.reInit(conversation);
|
conversationFragment.reInit(conversation);
|
||||||
|
if (mainNeedsRefresh) {
|
||||||
|
refreshFragment(R.id.main_fragment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,6 +174,8 @@ public class ConversationsMainActivity extends XmppActivity implements OnConvers
|
||||||
} else {
|
} else {
|
||||||
transaction.replace(R.id.main_fragment, new ConversationsOverviewFragment());
|
transaction.replace(R.id.main_fragment, new ConversationsOverviewFragment());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO, do this in backendConnected so we can actually decide what to display
|
||||||
if (binding.secondaryFragment != null) {
|
if (binding.secondaryFragment != null) {
|
||||||
transaction.replace(R.id.secondary_fragment, new ConversationFragment());
|
transaction.replace(R.id.secondary_fragment, new ConversationFragment());
|
||||||
}
|
}
|
||||||
|
@ -183,7 +206,10 @@ public class ConversationsMainActivity extends XmppActivity implements OnConvers
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConversationsListItemUpdated() {
|
public void onConversationsListItemUpdated() {
|
||||||
|
Fragment fragment = getFragmentManager().findFragmentById(R.id.main_fragment);
|
||||||
|
if (fragment != null && fragment instanceof ConversationsOverviewFragment) {
|
||||||
|
((ConversationsOverviewFragment) fragment).refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -47,9 +47,11 @@ import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.FragmentConversationsOverviewBinding;
|
import eu.siacs.conversations.databinding.FragmentConversationsOverviewBinding;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
|
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
|
||||||
|
import eu.siacs.conversations.ui.interfaces.OnConversationArchived;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
|
import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
|
||||||
|
import eu.siacs.conversations.ui.util.PendingItem;
|
||||||
|
|
||||||
public class ConversationsOverviewFragment extends XmppFragment {
|
public class ConversationsOverviewFragment extends XmppFragment implements EnhancedListView.OnDismissCallback {
|
||||||
|
|
||||||
private FragmentConversationsOverviewBinding binding;
|
private FragmentConversationsOverviewBinding binding;
|
||||||
|
|
||||||
|
@ -57,6 +59,8 @@ public class ConversationsOverviewFragment extends XmppFragment {
|
||||||
private ConversationAdapter conversationsAdapter;
|
private ConversationAdapter conversationsAdapter;
|
||||||
private XmppActivity activity;
|
private XmppActivity activity;
|
||||||
|
|
||||||
|
private final PendingItem<Conversation> swipedConversation = new PendingItem<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
|
@ -76,7 +80,6 @@ public class ConversationsOverviewFragment extends XmppFragment {
|
||||||
|
|
||||||
this.conversationsAdapter = new ConversationAdapter(this.activity, this.conversations);
|
this.conversationsAdapter = new ConversationAdapter(this.activity, this.conversations);
|
||||||
this.binding.list.setAdapter(this.conversationsAdapter);
|
this.binding.list.setAdapter(this.conversationsAdapter);
|
||||||
this.binding.list.setSwipeDirection(EnhancedListView.SwipeDirection.BOTH);
|
|
||||||
this.binding.list.setOnItemClickListener((parent, view, position, id) -> {
|
this.binding.list.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
Conversation conversation = this.conversations.get(position);
|
Conversation conversation = this.conversations.get(position);
|
||||||
if (activity instanceof OnConversationSelected) {
|
if (activity instanceof OnConversationSelected) {
|
||||||
|
@ -85,7 +88,13 @@ public class ConversationsOverviewFragment extends XmppFragment {
|
||||||
Log.w(ConversationsOverviewFragment.class.getCanonicalName(),"Activity does not implement OnConversationSelected");
|
Log.w(ConversationsOverviewFragment.class.getCanonicalName(),"Activity does not implement OnConversationSelected");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.binding.list.setDismissCallback(this);
|
||||||
|
this.binding.list.enableSwipeToDismiss();
|
||||||
|
this.binding.list.setSwipeDirection(EnhancedListView.SwipeDirection.BOTH);
|
||||||
|
this.binding.list.setSwipingLayout(R.id.swipeable_item);
|
||||||
|
this.binding.list.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP);
|
||||||
|
this.binding.list.setUndoHideDelay(5000);
|
||||||
|
this.binding.list.setRequireTouchBeforeDismiss(false);
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +122,72 @@ public class ConversationsOverviewFragment extends XmppFragment {
|
||||||
@Override
|
@Override
|
||||||
void refresh() {
|
void refresh() {
|
||||||
this.activity.xmppConnectionService.populateWithOrderedConversations(this.conversations);
|
this.activity.xmppConnectionService.populateWithOrderedConversations(this.conversations);
|
||||||
|
Conversation removed = this.swipedConversation.peek();
|
||||||
|
if (removed != null) {
|
||||||
|
if (removed.isRead()) {
|
||||||
|
this.conversations.remove(removed);
|
||||||
|
} else {
|
||||||
|
this.binding.list.discardUndo(); //will be ignored during discard when conversation is unRead
|
||||||
|
}
|
||||||
|
}
|
||||||
this.conversationsAdapter.notifyDataSetChanged();
|
this.conversationsAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnhancedListView.Undoable onDismiss(EnhancedListView listView, int position) {
|
||||||
|
try {
|
||||||
|
swipedConversation.push(this.conversationsAdapter.getItem(position));
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
this.conversationsAdapter.remove(swipedConversation.peek());
|
||||||
|
this.activity.xmppConnectionService.markRead(swipedConversation.peek());
|
||||||
|
|
||||||
|
if (position == 0 && this.conversationsAdapter.getCount() == 0) {
|
||||||
|
final Conversation c = swipedConversation.pop();
|
||||||
|
activity.xmppConnectionService.archiveConversation(c);
|
||||||
|
if (activity instanceof OnConversationArchived) {
|
||||||
|
((OnConversationArchived) activity).onConversationArchived(c);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final boolean formerlySelected = ConversationFragment.getConversation(getActivity()) == swipedConversation.peek();
|
||||||
|
if (activity instanceof OnConversationArchived) {
|
||||||
|
((OnConversationArchived) activity).onConversationArchived(swipedConversation.peek());
|
||||||
|
}
|
||||||
|
return new EnhancedListView.Undoable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo() {
|
||||||
|
Conversation c = swipedConversation.pop();
|
||||||
|
conversationsAdapter.insert(c, position);
|
||||||
|
if (formerlySelected) {
|
||||||
|
if (activity instanceof OnConversationSelected) {
|
||||||
|
((OnConversationSelected) activity).onConversationSelected(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (position > listView.getLastVisiblePosition()) {
|
||||||
|
listView.smoothScrollToPosition(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void discard() {
|
||||||
|
Conversation c = swipedConversation.pop();
|
||||||
|
if (!c.isRead() && c.getMode() == Conversation.MODE_SINGLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
activity.xmppConnectionService.archiveConversation(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
if (swipedConversation.peek().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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -19,11 +20,13 @@ import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.entities.Transferable;
|
import eu.siacs.conversations.entities.Transferable;
|
||||||
import eu.siacs.conversations.ui.ConversationActivity;
|
import eu.siacs.conversations.ui.ConversationActivity;
|
||||||
|
import eu.siacs.conversations.ui.ConversationFragment;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
import eu.siacs.conversations.ui.widget.UnreadCountCustomView;
|
import eu.siacs.conversations.ui.widget.UnreadCountCustomView;
|
||||||
import eu.siacs.conversations.utils.EmojiWrapper;
|
import eu.siacs.conversations.utils.EmojiWrapper;
|
||||||
|
@ -32,6 +35,7 @@ import eu.siacs.conversations.utils.UIHelper;
|
||||||
public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
|
|
||||||
private XmppActivity activity;
|
private XmppActivity activity;
|
||||||
|
private Conversation selectedConversation = null;
|
||||||
|
|
||||||
public ConversationAdapter(XmppActivity activity, List<Conversation> conversations) {
|
public ConversationAdapter(XmppActivity activity, List<Conversation> conversations) {
|
||||||
super(activity, 0, conversations);
|
super(activity, 0, conversations);
|
||||||
|
@ -45,10 +49,9 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
view = inflater.inflate(R.layout.conversation_list_row,parent, false);
|
view = inflater.inflate(R.layout.conversation_list_row,parent, false);
|
||||||
}
|
}
|
||||||
Conversation conversation = getItem(position);
|
Conversation conversation = getItem(position);
|
||||||
if (this.activity instanceof ConversationActivity) {
|
if (this.activity instanceof XmppActivity) {
|
||||||
View swipeableItem = view.findViewById(R.id.swipeable_item);
|
View swipeableItem = view.findViewById(R.id.swipeable_item);
|
||||||
ConversationActivity a = (ConversationActivity) this.activity;
|
int c = conversation == selectedConversation ? this.activity.getSecondaryBackgroundColor() : this.activity.getPrimaryBackgroundColor();
|
||||||
int c = a.highlightSelectedConversations() && conversation == a.getSelectedConversation() ? a.getSecondaryBackgroundColor() : a.getPrimaryBackgroundColor();
|
|
||||||
swipeableItem.setBackgroundColor(c);
|
swipeableItem.setBackgroundColor(c);
|
||||||
}
|
}
|
||||||
ViewHolder viewHolder = ViewHolder.get(view);
|
ViewHolder viewHolder = ViewHolder.get(view);
|
||||||
|
@ -168,6 +171,16 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyDataSetChanged() {
|
||||||
|
this.selectedConversation = ConversationFragment.getConversation(activity);
|
||||||
|
Log.d(Config.LOGTAG,"notify data set changed");
|
||||||
|
if (this.selectedConversation == null) {
|
||||||
|
Log.d(Config.LOGTAG,"selected conversation is null");
|
||||||
|
}
|
||||||
|
super.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
public static class ViewHolder {
|
public static class ViewHolder {
|
||||||
private TextView name;
|
private TextView name;
|
||||||
private TextView lastMessage;
|
private TextView lastMessage;
|
||||||
|
|
|
@ -32,5 +32,6 @@ package eu.siacs.conversations.ui.interfaces;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
|
|
||||||
public interface OnConversationArchived {
|
public interface OnConversationArchived {
|
||||||
|
|
||||||
void onConversationArchived(Conversation conversation);
|
void onConversationArchived(Conversation conversation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,4 +42,8 @@ public class PendingItem<T> {
|
||||||
this.item = null;
|
this.item = null;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized T peek() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -509,7 +509,7 @@
|
||||||
<string name="choose_quick_action">Choose quick action</string>
|
<string name="choose_quick_action">Choose quick action</string>
|
||||||
<string name="search_for_contacts_or_groups">Search for contacts or groups</string>
|
<string name="search_for_contacts_or_groups">Search for contacts or groups</string>
|
||||||
<string name="send_private_message">Send private message</string>
|
<string name="send_private_message">Send private message</string>
|
||||||
<string name="user_has_left_conference">%s has left the group chat!</string>
|
<string name="user_has_left_conference">%1$s has left the group chat!</string>
|
||||||
<string name="username">Username</string>
|
<string name="username">Username</string>
|
||||||
<string name="username_hint">Username</string>
|
<string name="username_hint">Username</string>
|
||||||
<string name="invalid_username">This is not a valid username</string>
|
<string name="invalid_username">This is not a valid username</string>
|
||||||
|
|
Loading…
Reference in New Issue