Swipe des chatrooms + suppression implantes. A faire: nettoyage et commentaires

This commit is contained in:
LuLe73 2018-05-30 13:14:13 +02:00 committed by Lucas Legrand
parent dbba5ca413
commit 6faa06a6b0
7 changed files with 375 additions and 172 deletions

View file

@ -6,7 +6,8 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:background="@drawable/list_selector">
android:foreground="?android:attr/selectableItemBackground"
android:background="@drawable/list_selector">
<CheckBox
android:id="@+id/delete_chatroom"
@ -122,5 +123,11 @@
</RelativeLayout>
</LinearLayout>
<View
android:id="@+id/selected_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/notification_color_led"
android:visibility="invisible" />
</RelativeLayout>

View file

@ -1,125 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:background="@drawable/list_selector">
<CheckBox
android:id="@+id/delete_chatroom"
android:button="@drawable/checkbox"
android:contentDescription="@string/content_description_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:visibility="invisible" android:layout_alignParentTop="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center">
<RelativeLayout
android:id="@+id/avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<ImageView
android:id="@+id/contact_picture"
android:src="@drawable/avatar"
android:contentDescription="@string/content_description_contact_picture"
android:layout_width="35dp"
android:layout_height="35dp"
android:adjustViewBounds="true"/>
<ImageView
android:id="@+id/mask"
android:src="@drawable/avatar_mask"
android:layout_width="35dp"
android:layout_height="35dp"
android:adjustViewBounds="true"/>
</RelativeLayout>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/avatar_layout"
android:layout_marginTop="5dp"
android:maxLines="1"
style="@style/font2"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@id/delete_chatroom"
android:paddingLeft="10dp">
<TextView
android:id="@+id/sipUri"
android:lines="1"
android:ellipsize="end"
android:scrollHorizontally="true"
android:maxLines="1"
style="@style/font6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="30dp"/>
<TextView
android:id="@+id/unreadMessages"
android:layout_width="20dp"
android:layout_height="20dp"
android:contentDescription="@string/content_description_unread_chat_message"
android:background="@drawable/chat_list_indicator"
style="@style/font18"
android:gravity="center"
android:maxLines="1"
android:layout_above="@+id/lastMessageLayout"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<LinearLayout
android:id="@id/lastMessageLayout"
android:layout_below="@id/sipUri"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/lastMessageSender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/font11"/>
<TextView
android:id="@+id/lastMessage"
android:maxLines="2"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="30dp"
style="@style/font11"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>

View file

@ -23,13 +23,16 @@ package org.linphone.chat;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -48,6 +51,8 @@ import org.linphone.core.ChatRoomListenerStub;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.ui.SwipeController;
import org.linphone.ui.SwipeControllerActions;
import java.util.ArrayList;
import java.util.Arrays;
@ -58,7 +63,7 @@ import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST;
//import android.widget.Toolbar;
//public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ListSelectionHelper.DeleteListener {
public class ChatListFragment extends Fragment implements ContactsUpdatedListener, /**ListSelectionHelper.DeleteListener,*/ ChatRoomsAdapter.ChatRoomViewHolder.ClickListener {
public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ChatRoomsAdapter.ChatRoomViewHolder.ClickListener {
//public class ChatListFragment extends Fragment {
private ActionModeCallback actionModeCallback = new ActionModeCallback();
@ -77,7 +82,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
private int mChatRoomDeletionPendingCount;
private ChatRoomListenerStub mChatRoomListener;
private Context mContext;
private List<ChatRoom> mRooms;
public List<ChatRoom> mRooms;
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -91,7 +96,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
View view = inflater.inflate(R.layout.chatlist, container, false);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);
Toolbar toolbar = this.getActivity().findViewById(R.id.context_bar);
// Toolbar toolbar = this.getActivity().findViewById(R.id.context_bar);
// mChatRoomsAdapter = new ChatRoomsAdapter(mContext, R.layout.chatlist_cell, mRooms);
mChatRoomsAdapter = new ChatRoomsAdapter(mContext, R.layout.chatlist_cell, mRooms,this);
@ -101,6 +106,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
// mSelectionHelper = new ListSelectionHelper(view, this);
// mChatRoomsAdapter = new ChatRoomsAdapter(this, mSelectionHelper, mRooms);
// mSelectionHelper.setAdapter(mChatRoomsAdapter);
@ -118,6 +124,33 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
mChatRoomsList.setLayoutManager(layoutManager);
// mNoChatHistory = view.findViewById(R.id.noChatHistory);
final SwipeController swipeController = new SwipeController(new SwipeControllerActions() {
@Override
public void onLeftClicked(int position) {
super.onLeftClicked(position);
}
@Override
public void onRightClicked(int position) {
mChatRoomsAdapter.removeItem(position);
// mChatRoomsAdapter.mRooms.remove(position);
// mChatRoomsAdapter.notifyItemRemoved(position);
// mChatRoomsAdapter.notifyItemRangeChanged(position, mChatRoomsAdapter.getItemCount());
}
});
ItemTouchHelper itemTouchhelper = new ItemTouchHelper(swipeController);
itemTouchhelper.attachToRecyclerView(mChatRoomsList);
mChatRoomsList.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
swipeController.onDraw(c);
}
});
// mNoChatHistory.setVisibility(View.GONE);
mEditTopBar = view.findViewById(R.id.edit_list);
mTopBar = view.findViewById(R.id.top_bar);
@ -128,12 +161,8 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
mEditButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
actionMode = getActivity().startActionMode(actionModeCallback);
// getActivity().setActionBar();
}
actionMode = getActivity().startActionMode(actionModeCallback);
}
});
mCancelButton = view.findViewById(R.id.cancel);
@ -177,6 +206,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
}
};
mChatRoomListener = new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom room, ChatRoom.State state) {
@ -199,6 +229,8 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
return view;
}
@Override
public void onItemClicked(int position) {
if (actionMode != null) {
@ -266,11 +298,11 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
actionMode.finish();
}
});
mTabBar = (LinearLayout) getActivity().findViewById(R.id.footer);
// mTabBar = (LinearLayout) getActivity().findViewById(R.id.footer);
// mTabBar.setVisibility(View.GONE);
mSideMenu=(DrawerLayout) getActivity().findViewById(R.id.side_menu);
mSideMenu.setDrawerLockMode(1);
// mSideMenu=(DrawerLayout) getActivity().findViewById(R.id.side_menu);
//
// mSideMenu.setDrawerLockMode(1);
//Add all non-selected items to the selection
mSelectAllButton.setOnClickListener(new View.OnClickListener() {
@ -437,32 +469,35 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
super.onPause();
}
@Override
public void onDeleteSelection(Object[] objectsToDelete) {
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
mChatRoomDeletionPendingCount = objectsToDelete.length;
for (Object obj : objectsToDelete) {
ChatRoom room = (ChatRoom)obj;
for (EventLog eventLog : room.getHistoryEvents(0)) {
if (eventLog.getType() == EventLog.Type.ConferenceChatMessage) {
ChatMessage message = eventLog.getChatMessage();
if (message.getAppdata() != null && !message.isOutgoing()) {
File file = new File(message.getAppdata());
if (file.exists()) {
file.delete(); // Delete downloaded file from incoming message that will be deleted
}
}
}
}
room.addListener(mChatRoomListener);
lc.deleteChatRoom(room);
}
if (mChatRoomDeletionPendingCount > 0) {
mWaitLayout.setVisibility(View.VISIBLE);
}
}
// @Override
// public void onDeleteSelection(Object[] objectsToDelete) {
// Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
// mChatRoomDeletionPendingCount = objectsToDelete.length;
// for (Object obj : objectsToDelete) {
// ChatRoom room = (ChatRoom)obj;
//
// for (EventLog eventLog : room.getHistoryEvents(0)) {
// if (eventLog.getType() == EventLog.Type.ConferenceChatMessage) {
// ChatMessage message = eventLog.getChatMessage();
// if (message.getAppdata() != null && !message.isOutgoing()) {
// File file = new File(message.getAppdata());
// if (file.exists()) {
// file.delete(); // Delete downloaded file from incoming message that will be deleted
// }
// }
// }
// }
//
// room.addListener(mChatRoomListener);
// lc.deleteChatRoom(room);
// }
// if (mChatRoomDeletionPendingCount > 0) {
// mWaitLayout.setVisibility(View.VISIBLE);
// }
// }
@Override
public void onContactsUpdated() {

View file

@ -22,8 +22,6 @@ package org.linphone.chat;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.widget.RecyclerView;
import android.view.ActionMode;
import android.view.LayoutInflater;
@ -31,10 +29,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
//import org.linphone.Chat;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneUtils;
import org.linphone.R;
@ -56,9 +53,11 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
//import org.linphone.Chat;
public class ChatRoomsAdapter extends RecyclerView.Adapter<ChatRoomsAdapter.ChatRoomViewHolder> {
public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public static class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
public TextView lastMessageSenderView;
public TextView lastMessageView;
public TextView date;
@ -68,6 +67,8 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter<ChatRoomsAdapter.Chat
public ImageView contactPicture;
public Context mContext;
public ChatRoom mRoom;
public ClickListener listener;
public RelativeLayout viewBackground, viewForeground;
public ChatRoomViewHolder(Context context,View itemView, ClickListener listener) {
@ -84,6 +85,7 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter<ChatRoomsAdapter.Chat
this.listener = listener;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
public void bindChatRoom(ChatRoom room) {
@ -191,7 +193,7 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter<ChatRoomsAdapter.Chat
}
private Context mContext;
private List<ChatRoom> mRooms;
public List<ChatRoom> mRooms;
private LayoutInflater mLayoutInflater;
private Bitmap mDefaultBitmap, mDefaultGroupBitmap;
private ChatRoomListenerStub mListener;
@ -202,7 +204,6 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter<ChatRoomsAdapter.Chat
// public ChatRoomsAdapter(Context context, int itemResource, List<ChatRoom> mRooms) {
public ChatRoomsAdapter(Context context, int itemResource, List<ChatRoom> mRooms, ChatRoomViewHolder.ClickListener clickListener) {
public ChatRoomsAdapter(Context context, int itemResource, List<ChatRoom> mRooms) {
super();
this.editionMode = false;
this.clickListener = clickListener;

View file

@ -1,4 +1,71 @@
package org.linphone.ui;
public abstract class SelectableAdapter {
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import java.util.ArrayList;
import java.util.List;
public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
@SuppressWarnings("unused")
private static final String TAG = SelectableAdapter.class.getSimpleName();
private SparseBooleanArray selectedItems;
public SelectableAdapter() {
selectedItems = new SparseBooleanArray();
}
/**
* Indicates if the item at position position is selected
* @param position Position of the item to check
* @return true if the item is selected, false otherwise
*/
public boolean isSelected(int position) {
return getSelectedItems().contains(position);
}
/**
* Toggle the selection status of the item at a given position
* @param position Position of the item to toggle the selection status for
*/
public void toggleSelection(int position) {
if (selectedItems.get(position, false)) {
selectedItems.delete(position);
} else {
selectedItems.put(position, true);
}
notifyItemChanged(position);
}
/**
* Clear the selection status for all items
*/
public void clearSelection() {
List<Integer> selection = getSelectedItems();
selectedItems.clear();
for (Integer i : selection) {
notifyItemChanged(i);
}
}
/**
* Count the selected items
* @return Selected items count
*/
public int getSelectedItemCount() {
return selectedItems.size();
}
/**
* Indicates the list of selected items
* @return List of selected items ids
*/
public List<Integer> getSelectedItems() {
List<Integer> items = new ArrayList<>(selectedItems.size());
for (int i = 0; i < selectedItems.size(); ++i) {
items.add(selectedItems.keyAt(i));
}
return items;
}
}

View file

@ -0,0 +1,211 @@
package org.linphone.ui;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper.Callback;
import android.view.MotionEvent;
import android.view.View;
import static android.support.v7.widget.helper.ItemTouchHelper.ACTION_STATE_SWIPE;
import static android.support.v7.widget.helper.ItemTouchHelper.LEFT;
enum ButtonsState {
GONE,
LEFT_VISIBLE,
RIGHT_VISIBLE
}
public class SwipeController extends Callback {
private boolean swipeBack = false;
private ButtonsState buttonShowedState = ButtonsState.GONE;
private RectF buttonInstance = null;
private RecyclerView.ViewHolder currentItemViewHolder = null;
private SwipeControllerActions buttonsActions = null;
private static final float buttonWidth = 300;
public SwipeController(SwipeControllerActions buttonsActions) {
this.buttonsActions = buttonsActions;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(0, LEFT);
// return makeMovementFlags(0, LEFT | RIGHT);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
if (swipeBack) {
swipeBack = false;
return 0;
}
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
@Override
public void onChildDraw(Canvas c,
RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
float dX, float dY,
int actionState, boolean isCurrentlyActive) {
if (actionState == ACTION_STATE_SWIPE) {
if (buttonShowedState != ButtonsState.GONE) {
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) dX = Math.max(dX, buttonWidth);
if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) dX = Math.min(dX, -buttonWidth);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}else {
setTouchListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
if (buttonShowedState == ButtonsState.GONE) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
currentItemViewHolder = viewHolder;
// drawButtons(c, viewHolder);
}
private void drawButtons(Canvas c, RecyclerView.ViewHolder viewHolder) {
float buttonWidthWithoutPadding = buttonWidth - 20;
float corners = 16;
View itemView = viewHolder.itemView;
Paint p = new Paint();
RectF leftButton = new RectF(itemView.getLeft(), itemView.getTop(), itemView.getLeft() + buttonWidthWithoutPadding, itemView.getBottom());
p.setColor(Color.BLUE);
c.drawRoundRect(leftButton, corners, corners, p);
drawText("EDIT", c, leftButton, p);
RectF rightButton = new RectF(itemView.getRight() - buttonWidthWithoutPadding, itemView.getTop(), itemView.getRight(), itemView.getBottom());
p.setColor(Color.RED);
c.drawRoundRect(rightButton, corners, corners, p);
drawText("DELETE", c, rightButton, p);
buttonInstance = null;
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
buttonInstance = leftButton;
}
else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
buttonInstance = rightButton;
}
}
private void drawText(String text, Canvas c, RectF button, Paint p) {
float textSize = 60;
p.setColor(Color.WHITE);
p.setAntiAlias(true);
p.setTextSize(textSize);
float textWidth = p.measureText(text);
c.drawText(text, button.centerX()-(textWidth/2), button.centerY()+(textSize/2), p);
}
private void setTouchListener(final Canvas c,
final RecyclerView recyclerView,
final RecyclerView.ViewHolder viewHolder,
final float dX, final float dY,
final int actionState, final boolean isCurrentlyActive) {
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
swipeBack = event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP;
if (swipeBack) {
if (dX < -buttonWidth) buttonShowedState = ButtonsState.RIGHT_VISIBLE;
else if (dX > buttonWidth) buttonShowedState = ButtonsState.LEFT_VISIBLE;
if (buttonShowedState != ButtonsState.GONE) {
setTouchDownListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
setItemsClickable(recyclerView, false);
}
}
return false;
}
});
}
private void setTouchDownListener(final Canvas c,
final RecyclerView recyclerView,
final RecyclerView.ViewHolder viewHolder,
final float dX, final float dY,
final int actionState, final boolean isCurrentlyActive) {
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
setTouchUpListener(c, recyclerView, viewHolder, dX, dY,
actionState, isCurrentlyActive);
}
return false;
}
});
}
private void setTouchUpListener(final Canvas c, final RecyclerView recyclerView,
final RecyclerView.ViewHolder viewHolder,
final float dX, final float dY,
final int actionState, final boolean isCurrentlyActive) {
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
SwipeController.super.onChildDraw(c, recyclerView, viewHolder, 0F, dY, actionState, isCurrentlyActive);
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
setItemsClickable(recyclerView, true);
swipeBack = false;
if (buttonsActions != null && buttonInstance != null && buttonInstance.contains(event.getX(), event.getY())) {
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
buttonsActions.onLeftClicked(viewHolder.getAdapterPosition());
}
else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
buttonsActions.onRightClicked(viewHolder.getAdapterPosition());
}
}
buttonShowedState = ButtonsState.GONE;
currentItemViewHolder = null;
}
return false;
}
});
}
private void setItemsClickable(RecyclerView recyclerView, boolean isClickable) {
for (int i = 0; i < recyclerView.getChildCount(); ++i) {
recyclerView.getChildAt(i).setClickable(isClickable);
}
}
public void onDraw(Canvas c) {
if (currentItemViewHolder != null) {
drawButtons(c, currentItemViewHolder);
}
}
}

View file

@ -0,0 +1,7 @@
package org.linphone.ui;
public abstract class SwipeControllerActions {
public void onLeftClicked(int position) {}
public void onRightClicked(int position) {}
}