From 8006231a698f380381d25a2603c82561478585e7 Mon Sep 17 00:00:00 2001 From: Lucas Legrand Date: Fri, 22 Jun 2018 14:19:41 +0200 Subject: [PATCH 01/25] Correction de la date de reception de message --- build.gradle | 3 +- doc/CustomsParameters.txt | 72 ---- gradle.properties | 8 - liblinphone_tester/Makefile | 59 --- res/layout/chatlist.xml | 2 +- res/layout/chatlist_cell_active.xml | 125 ++++++ res/menu/edit_list_menu.xml | 58 +++ res/raw/lpconfig.xsd | 45 -- sample/libs | 1 - .../org/linphone/chat/ChatListFragment.java | 40 +- .../org/linphone/chat/ChatRoomsAdapter.java | 389 +++++++++++------- .../org/linphone/ui/SelectableAdapter.java | 4 + 12 files changed, 460 insertions(+), 346 deletions(-) delete mode 100644 doc/CustomsParameters.txt delete mode 100644 gradle.properties delete mode 100644 liblinphone_tester/Makefile create mode 100644 res/layout/chatlist_cell_active.xml create mode 100644 res/menu/edit_list_menu.xml delete mode 100644 res/raw/lpconfig.xsd delete mode 120000 sample/libs create mode 100644 src/android/org/linphone/ui/SelectableAdapter.java diff --git a/build.gradle b/build.gradle index f35eb40de..a02701e81 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,8 @@ dependencies { if (firebaseEnable()) { implementation 'com.google.firebase:firebase-messaging:12.0.1' } - implementation 'com.android.support:support-v4:26.0.1' + implementation 'com.android.support:support-v4:27.1.1' + implementation 'com.android.support:recyclerview-v7:27.1.1' } if (firebaseEnable()) { diff --git a/doc/CustomsParameters.txt b/doc/CustomsParameters.txt deleted file mode 100644 index dc39dbba5..000000000 --- a/doc/CustomsParameters.txt +++ /dev/null @@ -1,72 +0,0 @@ - ********************************** - * LINPHONE customs parameters * - ********************************** - -In res/values/non_localizable_custom.xml (filled with linphone default options): - -1. Global - - * Set the default domain used by the application: - sip.linphone.orghttps://sip3.linphone.org:444/inapp.php - - * In CreateAccount, allow username instead of phone number for creating a new account - true - - * Hide buttons in assistant menu - false - false - false - - -3. Inapp - - * Enabled inapp purchase - true - - * Days before end of trial period that launch daily notification to remind user to buy an account - 5 - - * Time between two inapp notifications in seconds - 86400 - - * Hide username field in purchase view (automatically get from default account) - true - - -In res/raw/linphonerc_factory sections: - - [in-app-purchase] - * Server xmlrpc url for inapp - server_url=https://sip3.linphone.org:444/inapp.php - - * Item ids from the google play store - purchasable_items_ids=test_account_subscription - - [app] - - * Numbers of digits to enter for validation/recover account - activation_code_length=4 - - - [assistant] - - * Set the default domain used for account creation : - domain=sip.linphone.org - - * Set the default password length (min-max) : - password_max_length=-1 - password_min_length=1 - - * Set the default username length (min-max) : - username_length=-1 - username_max_length=64 - username_min_length=1 - username_regex=^[a-z0-9_.\-]*$ - - * Server xmlrpc url for accounts - xmlrpc_url=https://sip3.linphone.org:444/inapp.php diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 4aca4f094..000000000 --- a/gradle.properties +++ /dev/null @@ -1,8 +0,0 @@ -// Signing APK Release -RELEASE_STORE_FILE="" -RELEASE_STORE_PASSWORD= -RELEASE_KEY_ALIAS= -RELEASE_KEY_PASSWORD= - -org.gradle.jvmargs=-XX\:MaxHeapSize\=2048M -Xmx2048M -#org.gradle.jvmargs=-Xmx1536M diff --git a/liblinphone_tester/Makefile b/liblinphone_tester/Makefile deleted file mode 100644 index 7f7ce7d6a..000000000 --- a/liblinphone_tester/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -all: copy-files - ../gradlew clean - ../gradlew uninstallDebug - -run-all-tests: copy-files - ../gradlew :installDebugAndroidTest && \ - ../gradlew :installDebug && \ - ../gradlew :grantDebugPermissions -i && \ - ../gradlew :connectedAndroidTest -i \ - -copy-libs: - mkdir -p assets && \ - mkdir -p assets/config_files && \ - rm -rf libs/arm64-v8a - if test -d "../liblinphone-sdk/android-arm64"; then \ - mkdir -p libs/arm64-v8a && \ - cp -f ../liblinphone-sdk/android-arm64/lib/*.so libs/arm64-v8a && \ - cp -f ../liblinphone-sdk/android-arm64/lib/mediastreamer/plugins/*.so libs/arm64-v8a && \ - cp -f ../liblinphone-sdk/android-arm64/share/linphone/rootca.pem assets/config_files; \ - fi - if test -f "../liblinphone-sdk/android-arm64/bin/gdbserver"; then \ - cp -f ../liblinphone-sdk/android-arm64/bin/gdbserver libs/arm64-v8a && \ - cp -f ../liblinphone-sdk/android-arm64/bin/gdb.setup libs/arm64-v8a; \ - fi - rm -rf libs/armeabi-v7a - if test -d "../liblinphone-sdk/android-armv7"; then \ - mkdir -p libs/armeabi-v7a && \ - cp -f ../liblinphone-sdk/android-armv7/lib/*.so libs/armeabi-v7a && \ - cp -f ../liblinphone-sdk/android-armv7/lib/mediastreamer/plugins/*.so libs/armeabi-v7a && \ - cp -f ../liblinphone-sdk/android-armv7/share/linphone/rootca.pem assets/config_files; \ - fi - if test -f "../liblinphone-sdk/android-armv7/bin/gdbserver"; then \ - cp -f ../liblinphone-sdk/android-armv7/bin/gdbserver libs/armeabi-v7a && \ - cp -f ../liblinphone-sdk/android-armv7/bin/gdb.setup libs/armeabi-v7a; \ - fi - rm -rf libs/x86 - if test -d "../liblinphone-sdk/android-x86"; then \ - mkdir -p libs/x86 && \ - cp -f ../liblinphone-sdk/android-x86/lib/*.so libs/x86 && \ - cp -f ../liblinphone-sdk/android-x86/lib/mediastreamer/plugins/*.so libs/x86 && \ - cp -f ../liblinphone-sdk/android-x86/share/linphone/rootca.pem assets/config_files; \ - fi - if test -f "../liblinphone-sdk/android-x86/bin/gdbserver"; then \ - cp -f ../liblinphone-sdk/android-x86/bin/gdbserver libs/x86 && \ - cp -f ../liblinphone-sdk/android-x86/bin/gdb.setup libs/x86; \ - fi - -copy-files: ../submodules/linphone/tester/tester_hosts - $(MAKE) copy-libs - rm -rf assets/config_files - mkdir -p assets/config_files - for file in $^; do \ - cp -rf $$file assets/config_files/. ; \ - done - cp -rf ../submodules/linphone/tester/certificates assets/config_files - cp -rf ../submodules/linphone/tester/images assets/config_files - cp -rf ../submodules/linphone/tester/rcfiles assets/config_files - cp -rf ../submodules/linphone/tester/sounds assets/config_files - cp -rf ../submodules/linphone/tester/vcards assets/config_files diff --git a/res/layout/chatlist.xml b/res/layout/chatlist.xml index 70af2f015..82ec2e2dc 100644 --- a/res/layout/chatlist.xml +++ b/res/layout/chatlist.xml @@ -55,7 +55,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/menu/edit_list_menu.xml b/res/menu/edit_list_menu.xml new file mode 100644 index 000000000..e6e24d02f --- /dev/null +++ b/res/menu/edit_list_menu.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/raw/lpconfig.xsd b/res/raw/lpconfig.xsd deleted file mode 100644 index 49bb56180..000000000 --- a/res/raw/lpconfig.xsd +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sample/libs b/sample/libs deleted file mode 120000 index d4bda9b46..000000000 --- a/sample/libs +++ /dev/null @@ -1 +0,0 @@ -../libs \ No newline at end of file diff --git a/src/android/org/linphone/chat/ChatListFragment.java b/src/android/org/linphone/chat/ChatListFragment.java index f7fb2ec16..a1e668fe8 100644 --- a/src/android/org/linphone/chat/ChatListFragment.java +++ b/src/android/org/linphone/chat/ChatListFragment.java @@ -20,7 +20,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package org.linphone.chat; import android.app.Fragment; +import android.content.Context; import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -47,12 +50,16 @@ import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST; public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ListSelectionHelper.DeleteListener { - private LayoutInflater mInflater; - private ListView mChatRoomsList; +//public class ChatListFragment extends Fragment { + // private LayoutInflater mInflater; + private RecyclerView mChatRoomsList; private TextView mNoChatHistory; private ImageView mNewDiscussionButton, mBackToCallButton; private ChatRoomsAdapter mChatRoomsAdapter; @@ -61,23 +68,31 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene private RelativeLayout mWaitLayout; private int mChatRoomDeletionPendingCount; private ChatRoomListenerStub mChatRoomListener; + private Context mContext; + private List mRooms; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mInflater = inflater; +// mInflater = inflater; + super.onCreate(savedInstanceState); + mRooms = new ArrayList<>(Arrays.asList(LinphoneManager.getLc().getChatRooms())); + this.mContext = getActivity().getApplicationContext(); View view = inflater.inflate(R.layout.chatlist, container, false); - mSelectionHelper = new ListSelectionHelper(view, this); - mChatRoomsAdapter = new ChatRoomsAdapter(getActivity(), mSelectionHelper, mInflater); - mSelectionHelper.setAdapter(mChatRoomsAdapter); - mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog); + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext); + + mChatRoomsAdapter = new ChatRoomsAdapter(mContext, R.layout.chatlist_cell, mRooms); +// mSelectionHelper = new ListSelectionHelper(view, this); +// mChatRoomsAdapter = new ChatRoomsAdapter(this, mSelectionHelper, mRooms); +// mSelectionHelper.setAdapter(mChatRoomsAdapter); +// mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog); mWaitLayout = view.findViewById(R.id.waitScreen); mWaitLayout.setVisibility(View.GONE); mChatRoomsList = view.findViewById(R.id.chatList); mChatRoomsList.setAdapter(mChatRoomsAdapter); - + mChatRoomsList.setLayoutManager(layoutManager); mNoChatHistory = view.findViewById(R.id.noChatHistory); mNoChatHistory.setVisibility(View.GONE); @@ -135,12 +150,12 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene private void refreshChatRoomsList() { mChatRoomsAdapter.refresh(); - mNoChatHistory.setVisibility(mChatRoomsAdapter.getCount() == 0 ? View.VISIBLE : View.GONE); + mNoChatHistory.setVisibility(mChatRoomsAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); } public void displayFirstChat() { ChatRoomsAdapter adapter = (ChatRoomsAdapter)mChatRoomsList.getAdapter(); - if (adapter != null && adapter.getCount() > 0) { + if (adapter != null && adapter.getItemCount() > 0) { ChatRoom room = (ChatRoom) adapter.getItem(0); LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly()); } else { @@ -210,16 +225,15 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene } } - @Override + @Override public void onContactsUpdated() { if (!LinphoneActivity.isInstanciated() || LinphoneActivity.instance().getCurrentFragment() != CHAT_LIST) return; ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter(); if (adapter != null) { - adapter.notifyDataSetInvalidated(); + //adapter.notifyDataSetInvalidated(); } } } - diff --git a/src/android/org/linphone/chat/ChatRoomsAdapter.java b/src/android/org/linphone/chat/ChatRoomsAdapter.java index fe510fe95..3775c1ee5 100644 --- a/src/android/org/linphone/chat/ChatRoomsAdapter.java +++ b/src/android/org/linphone/chat/ChatRoomsAdapter.java @@ -22,14 +22,18 @@ package org.linphone.chat; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.graphics.Typeface; +import android.net.Uri; +import android.provider.MediaStore; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; +//import org.linphone.Chat; import org.linphone.LinphoneManager; import org.linphone.LinphoneUtils; import org.linphone.R; @@ -39,21 +43,19 @@ import org.linphone.contacts.LinphoneContact; import org.linphone.core.Address; import org.linphone.core.ChatMessage; import org.linphone.core.ChatRoom; -import org.linphone.core.ChatRoomCapabilities; import org.linphone.core.ChatRoomListenerStub; -import org.linphone.core.EventLog; -import org.linphone.ui.ListSelectionAdapter; -import org.linphone.ui.ListSelectionHelper; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; -public class ChatRoomsAdapter extends ListSelectionAdapter { +public class ChatRoomsAdapter extends RecyclerView.Adapter { - private class ChatRoomViewHolder { + public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView lastMessageSenderView; public TextView lastMessageView; public TextView date; @@ -61,16 +63,81 @@ public class ChatRoomsAdapter extends ListSelectionAdapter { public TextView unreadMessages; public CheckBox delete; public ImageView contactPicture; + public Context mContext; + public ChatRoom mRoom; - public ChatRoomViewHolder(View view) { - lastMessageSenderView = view.findViewById(R.id.lastMessageSender); - lastMessageView = view.findViewById(R.id.lastMessage); - date = view.findViewById(R.id.date); - displayName = view.findViewById(R.id.sipUri); - unreadMessages = view.findViewById(R.id.unreadMessages); - delete = view.findViewById(R.id.delete_chatroom); - contactPicture = view.findViewById(R.id.contact_picture); + public ChatRoomViewHolder(Context context,View itemView) { + super(itemView); + this.mContext= context; + this.lastMessageSenderView = itemView.findViewById(R.id.lastMessageSender); + this.lastMessageView = itemView.findViewById(R.id.lastMessage); + this.date = itemView.findViewById(R.id.date); + this.displayName = itemView.findViewById(R.id.sipUri); + this.unreadMessages = itemView.findViewById(R.id.unreadMessages); + this.delete = itemView.findViewById(R.id.delete_chatroom); + this.contactPicture = itemView.findViewById(R.id.contact_picture); + itemView.setOnClickListener(this); } + public void bindChatRoom(ChatRoom room) { + + // 4. Bind the data to the ViewHolder + this.mRoom = room; + this.lastMessageSenderView.setText(getSender(mRoom)); + this.lastMessageView.setText(mRoom.getLastMessageInHistory() != null ? mRoom.getLastMessageInHistory().getTextContent(): ""); + this.date.setText(mRoom.getLastMessageInHistory()!=null ? LinphoneUtils.timestampToHumanDate(this.mContext, mRoom.getLastUpdateTime(), R.string.messages_list_date_format) : ""); + this.displayName.setText(getContact(mRoom)); + this.unreadMessages.setText(String.valueOf(LinphoneManager.getInstance().getUnreadCountForChatRoom(mRoom))); + this.delete.setChecked(!this.delete.isChecked()); + getAvatar(mRoom); + + } + + @Override + public void onClick(View v) { + + // 5. Handle the onClick event for the ViewHolder + if (this.mRoom != null) { + LinphoneActivity.instance().goToChat(mRoom.getPeerAddress().asString()); + } + } + + public String getSender(ChatRoom mRoom){ + if (mRoom.getLastMessageInHistory() != null) { + LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(mRoom.getLastMessageInHistory().getFromAddress()); + if (contact != null) { + return (contact.getFullName() + mContext.getString(R.string.separator)); + } else { + return (LinphoneUtils.getAddressDisplayName(mRoom.getLastMessageInHistory().getFromAddress()) + ":"); + } + }else{ + return "" ; + } + } + + public String getContact(ChatRoom mRoom) { + LinphoneContact contact; + contact = ContactsManager.getInstance().findContactFromAddress(mRoom.getPeerAddress()); + if (contact != null) { + + return (contact.getFullName()); + + } else { + return (LinphoneUtils.getAddressDisplayName(mRoom.getPeerAddress())); + } + } + public void getAvatar(ChatRoom mRoom) { + mDefaultBitmap = ContactsManager.getInstance().getDefaultAvatarBitmap(); + LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(mRoom.getPeerAddress()); + if (contact != null) { + LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), this.contactPicture, ContactsManager.getInstance().findContactFromAddress(mRoom.getPeerAddress()).getThumbnailUri()); + } else { + this.contactPicture.setImageBitmap(mDefaultBitmap); + } + } + + + + } private Context mContext; @@ -78,22 +145,45 @@ public class ChatRoomsAdapter extends ListSelectionAdapter { private LayoutInflater mLayoutInflater; private Bitmap mDefaultBitmap, mDefaultGroupBitmap; private ChatRoomListenerStub mListener; + private int itemResource; - public ChatRoomsAdapter(Context context, ListSelectionHelper helper, LayoutInflater inflater) { - super(helper); + public ChatRoomsAdapter(Context context, int itemResource, List mRooms) { + super(); + this.mRooms = mRooms; + this.mContext = context; + this.itemResource = itemResource; mContext = context; - mLayoutInflater = inflater; - mRooms = new ArrayList<>(); + //mLayoutInflater = inflater; mDefaultBitmap = ContactsManager.getInstance().getDefaultAvatarBitmap(); mDefaultGroupBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chat_group_avatar); - mListener = new ChatRoomListenerStub() { - @Override - public void onSubjectChanged(ChatRoom cr, EventLog eventLog) { - ChatRoomViewHolder holder = (ChatRoomViewHolder) cr.getUserData(); - holder.displayName.setText(cr.getSubject()); - } - }; +// mListener = new ChatRoomListenerStub() { +// @Override +// public void onSubjectChanged(ChatRoom cr, EventLog eventLog) { +// ChatRoomViewHolder holder = (ChatRoomViewHolder) cr.getUserData(); +// holder.displayName.setText(cr.getSubject()); +// } +// }; + + } + + @Override + public ChatRoomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + + // 3. Inflate the view and return the new ViewHolder + View view = LayoutInflater.from(parent.getContext()) + .inflate(this.itemResource, parent, false); + return new ChatRoomViewHolder(this.mContext, view); + } + + @Override + public void onBindViewHolder(ChatRoomViewHolder holder, int position) { + + // 5. Use position to access the correct Bakery object + ChatRoom room = this.mRooms.get(position); + + // 6. Bind the bakery object to the holder + holder.bindChatRoom(room); } public void refresh() { @@ -120,12 +210,19 @@ public class ChatRoomsAdapter extends ListSelectionAdapter { * Adapter's methods */ - @Override - public int getCount() { - return mRooms.size(); - } +// @Override +// public int getCount() { +// return mRooms.size(); +// } @Override + public int getItemCount() { + + return this.mRooms.size(); + } + + + //@Override public Object getItem(int position) { return mRooms.get(position); } @@ -135,120 +232,120 @@ public class ChatRoomsAdapter extends ListSelectionAdapter { return position; } - @Override - public View getView(final int position, View convertView, ViewGroup viewGroup) { - View view; - ChatRoomViewHolder holder; - - if (convertView != null) { - view = convertView; - holder = (ChatRoomViewHolder) view.getTag(); - } else { - view = mLayoutInflater.inflate(R.layout.chatlist_cell, viewGroup, false); - holder = new ChatRoomViewHolder(view); - view.setTag(holder); - } - - ChatRoom chatRoom = mRooms.get(position); - Address remoteAddress = chatRoom.getPeerAddress(); - Address contactAddress = remoteAddress; - - if (chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) && chatRoom.getParticipants().length > 0) { - contactAddress = chatRoom.getParticipants()[0].getAddress(); - } - - if (chatRoom.hasCapability(ChatRoomCapabilities.Conference.toInt()) && chatRoom.getState() == ChatRoom.State.Created) { // Only set for state Created otherwise it will conflict with removal listener - chatRoom.addListener(mListener); - chatRoom.setUserData(holder); - } - - int unreadMessagesCount = LinphoneManager.getInstance().getUnreadCountForChatRoom(chatRoom); - ChatMessage lastMessage = chatRoom.getLastMessageInHistory(); - holder.lastMessageView.setText(""); - holder.lastMessageSenderView.setText(""); - holder.date.setText(LinphoneUtils.timestampToHumanDate(mContext, chatRoom.getLastUpdateTime(), R.string.messages_list_date_format)); - - if (lastMessage != null) { - if (lastMessage.getFileTransferInformation() != null || lastMessage.getExternalBodyUrl() != null || lastMessage.getAppdata() != null) { - holder.lastMessageView.setBackgroundResource(R.drawable.chat_file_message); - } else if (lastMessage.getTextContent() != null && lastMessage.getTextContent().length() > 0) { - holder.lastMessageView.setBackgroundResource(0); - holder.lastMessageView.setText(lastMessage.getTextContent()); - } - - Address lastMessageSenderAddress = lastMessage.getFromAddress(); - LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(lastMessageSenderAddress); - if (contact != null) { - holder.lastMessageSenderView.setText(contact.getFullName() + mContext.getString(R.string.separator)); - } else { - holder.lastMessageSenderView.setText(LinphoneUtils.getAddressDisplayName(lastMessageSenderAddress) + mContext.getString(R.string.separator)); - } - } - - holder.displayName.setSelected(true); // For animation - holder.contactPicture.setImageBitmap(mDefaultBitmap); - - if (chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { - LinphoneContact contact; - if (chatRoom.getParticipants().length > 0) { - contact = ContactsManager.getInstance().findContactFromAddress(chatRoom.getParticipants()[0].getAddress()); - if (contact != null) { - holder.displayName.setText(contact.getFullName()); - LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri()); - } else { - holder.displayName.setText(LinphoneUtils.getAddressDisplayName(chatRoom.getParticipants()[0].getAddress())); - } - } else { - contact = ContactsManager.getInstance().findContactFromAddress(contactAddress); - if (contact != null) { - holder.displayName.setText(contact.getFullName()); - LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri()); - } else { - holder.displayName.setText(LinphoneUtils.getAddressDisplayName(contactAddress)); - } - } - } else { - holder.displayName.setText(chatRoom.getSubject()); - holder.contactPicture.setImageBitmap(mDefaultGroupBitmap); - } - - if (unreadMessagesCount > 0) { - holder.unreadMessages.setVisibility(View.VISIBLE); - holder.unreadMessages.setText(String.valueOf(unreadMessagesCount)); - if (unreadMessagesCount > 99) { - holder.unreadMessages.setTextSize(12); - } - holder.unreadMessages.setVisibility(View.VISIBLE); - holder.displayName.setTypeface(null, Typeface.BOLD); - } else { - holder.unreadMessages.setVisibility(View.GONE); - holder.displayName.setTypeface(null, Typeface.NORMAL); - } - - if (isEditionEnabled()) { - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ChatRoomViewHolder holder = (ChatRoomViewHolder)v.getTag(); - holder.delete.setChecked(!holder.delete.isChecked()); - } - }); - holder.unreadMessages.setVisibility(View.GONE); - holder.delete.setOnCheckedChangeListener(null); - holder.delete.setVisibility(View.VISIBLE); - holder.delete.setChecked(getSelectedItemsPosition().contains(position)); - holder.delete.setTag(position); - holder.delete.setOnCheckedChangeListener(getDeleteListener()); - } else { - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ChatRoom chatRoom = mRooms.get(position); - LinphoneActivity.instance().goToChat(chatRoom.getPeerAddress().asString()); - } - }); - holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE); - } - return view; - } +// @Override +// public View getView(final int position, View convertView, ViewGroup viewGroup) { +// View view; +// ChatRoomViewHolder holder; +// +// if (convertView != null) { +// view = convertView; +// holder = (ChatRoomViewHolder) view.getTag(); +// } else { +// view = mLayoutInflater.inflate(R.layout.chatlist_cell, viewGroup, false); +// holder = new ChatRoomViewHolder(view); +// view.setTag(holder); +// } +// +// ChatRoom chatRoom = mRooms.get(position); +// Address remoteAddress = chatRoom.getPeerAddress(); +// Address contactAddress = remoteAddress; +// +// if (chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) && chatRoom.getParticipants().length > 0) { +// contactAddress = chatRoom.getParticipants()[0].getAddress(); +// } +// +// if (chatRoom.hasCapability(ChatRoomCapabilities.Conference.toInt()) && chatRoom.getState() == ChatRoom.State.Created) { // Only set for state Created otherwise it will conflict with removal listener +// chatRoom.addListener(mListener); +// chatRoom.setUserData(holder); +// } +// +// int unreadMessagesCount = LinphoneManager.getInstance().getUnreadCountForChatRoom(chatRoom); +// ChatMessage lastMessage = chatRoom.getLastMessageInHistory(); +// holder.lastMessageView.setText(""); +// holder.lastMessageSenderView.setText(""); +// holder.date.setText(LinphoneUtils.timestampToHumanDate(mContext, chatRoom.getLastUpdateTime(), R.string.messages_list_date_format)); +// +// if (lastMessage != null) { +// if (lastMessage.getFileTransferInformation() != null || lastMessage.getExternalBodyUrl() != null || lastMessage.getAppdata() != null) { +// holder.lastMessageView.setBackgroundResource(R.drawable.chat_file_message); +// } else if (lastMessage.getTextContent() != null && lastMessage.getTextContent().length() > 0) { +// holder.lastMessageView.setBackgroundResource(0); +// holder.lastMessageView.setText(lastMessage.getTextContent()); +// } +// +// Address lastMessageSenderAddress = lastMessage.getFromAddress(); +// LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(lastMessageSenderAddress); +// if (contact != null) { +// holder.lastMessageSenderView.setText(contact.getFullName() + mContext.getString(R.string.separator)); +// } else { +// holder.lastMessageSenderView.setText(LinphoneUtils.getAddressDisplayName(lastMessageSenderAddress) + mContext.getString(R.string.separator)); +// } +// } +// +// holder.displayName.setSelected(true); // For animation +// holder.contactPicture.setImageBitmap(mDefaultBitmap); +// +// if (chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { +// LinphoneContact contact; +// if (chatRoom.getParticipants().length > 0) { +// contact = ContactsManager.getInstance().findContactFromAddress(chatRoom.getParticipants()[0].getAddress()); +// if (contact != null) { +// holder.displayName.setText(contact.getFullName()); +// LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri()); +// } else { +// holder.displayName.setText(LinphoneUtils.getAddressDisplayName(chatRoom.getParticipants()[0].getAddress())); +// } +// } else { +// contact = ContactsManager.getInstance().findContactFromAddress(contactAddress); +// if (contact != null) { +// holder.displayName.setText(contact.getFullName()); +// LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri()); +// } else { +// holder.displayName.setText(LinphoneUtils.getAddressDisplayName(contactAddress)); +// } +// } +// } else { +// holder.displayName.setText(chatRoom.getSubject()); +// holder.contactPicture.setImageBitmap(mDefaultGroupBitmap); +// } +// +// if (unreadMessagesCount > 0) { +// holder.unreadMessages.setVisibility(View.VISIBLE); +// holder.unreadMessages.setText(String.valueOf(unreadMessagesCount)); +// if (unreadMessagesCount > 99) { +// holder.unreadMessages.setTextSize(12); +// } +// holder.unreadMessages.setVisibility(View.VISIBLE); +// holder.displayName.setTypeface(null, Typeface.BOLD); +// } else { +// holder.unreadMessages.setVisibility(View.GONE); +// holder.displayName.setTypeface(null, Typeface.NORMAL); +// } +// +// if (isEditionEnabled()) { +// view.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View v) { +// ChatRoomViewHolder holder = (ChatRoomViewHolder)v.getTag(); +// holder.delete.setChecked(!holder.delete.isChecked()); +// } +// }); +// holder.unreadMessages.setVisibility(View.GONE); +// holder.delete.setOnCheckedChangeListener(null); +// holder.delete.setVisibility(View.VISIBLE); +// holder.delete.setChecked(getSelectedItemsPosition().contains(position)); +// holder.delete.setTag(position); +// holder.delete.setOnCheckedChangeListener(getDeleteListener()); +// } else { +// view.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View v) { +// ChatRoom chatRoom = mRooms.get(position); +// LinphoneActivity.instance().goToChat(chatRoom.getPeerAddress().asString()); +// } +// }); +// holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE); +// } +// return view; +// } } diff --git a/src/android/org/linphone/ui/SelectableAdapter.java b/src/android/org/linphone/ui/SelectableAdapter.java new file mode 100644 index 000000000..00d12b9fd --- /dev/null +++ b/src/android/org/linphone/ui/SelectableAdapter.java @@ -0,0 +1,4 @@ +package org.linphone.ui; + +public abstract class SelectableAdapter { +} From 10565fd63671910c26a4adcfea9c90416736d1be Mon Sep 17 00:00:00 2001 From: LuLe73 Date: Wed, 23 May 2018 17:10:27 +0200 Subject: [PATCH 02/25] =?UTF-8?q?Selection=20des=20items=20achev=C3=83ee,?= =?UTF-8?q?=20selection=20totale,=20annulation,=20affichage=20des=20bouton?= =?UTF-8?q?s=20contextuels.=20A=20ajouter=20la=20suppression,=20deselectio?= =?UTF-8?q?n=20totale.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- res/layout/chatlist_cell.xml | 1 + .../org/linphone/chat/ChatListFragment.java | 173 +++++++++++++++++- .../org/linphone/chat/ChatRoomsAdapter.java | 47 ++++- 3 files changed, 214 insertions(+), 7 deletions(-) diff --git a/res/layout/chatlist_cell.xml b/res/layout/chatlist_cell.xml index 6989dc64e..99aefd1ff 100644 --- a/res/layout/chatlist_cell.xml +++ b/res/layout/chatlist_cell.xml @@ -14,6 +14,7 @@ android:contentDescription="@string/content_description_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:clickable="false" android:adjustViewBounds="true" android:layout_alignParentRight="true" android:layout_centerVertical="true" diff --git a/src/android/org/linphone/chat/ChatListFragment.java b/src/android/org/linphone/chat/ChatListFragment.java index a1e668fe8..59fd4d517 100644 --- a/src/android/org/linphone/chat/ChatListFragment.java +++ b/src/android/org/linphone/chat/ChatListFragment.java @@ -27,9 +27,11 @@ import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.Window; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; @@ -59,12 +61,16 @@ import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST; public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ListSelectionHelper.DeleteListener { //public class ChatListFragment extends Fragment { // private LayoutInflater mInflater; + private ActionModeCallback actionModeCallback = new ActionModeCallback(); + private ActionMode actionMode; + private LinearLayout mEditTopBar, mTopBar; + private ImageView mEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton, mCancelButton; private RecyclerView mChatRoomsList; private TextView mNoChatHistory; private ImageView mNewDiscussionButton, mBackToCallButton; private ChatRoomsAdapter mChatRoomsAdapter; private CoreListenerStub mListener; - private ListSelectionHelper mSelectionHelper; +// private ListSelectionHelper mSelectionHelper; private RelativeLayout mWaitLayout; private int mChatRoomDeletionPendingCount; private ChatRoomListenerStub mChatRoomListener; @@ -76,6 +82,8 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene // mInflater = inflater; super.onCreate(savedInstanceState); + + setHasOptionsMenu(true); mRooms = new ArrayList<>(Arrays.asList(LinphoneManager.getLc().getChatRooms())); this.mContext = getActivity().getApplicationContext(); View view = inflater.inflate(R.layout.chatlist, container, false); @@ -87,14 +95,43 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene // mSelectionHelper.setAdapter(mChatRoomsAdapter); // mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog); + + + + mWaitLayout = view.findViewById(R.id.waitScreen); mWaitLayout.setVisibility(View.GONE); mChatRoomsList = view.findViewById(R.id.chatList); mChatRoomsList.setAdapter(mChatRoomsAdapter); mChatRoomsList.setLayoutManager(layoutManager); - mNoChatHistory = view.findViewById(R.id.noChatHistory); - mNoChatHistory.setVisibility(View.GONE); +// mNoChatHistory = view.findViewById(R.id.noChatHistory); + +// mNoChatHistory.setVisibility(View.GONE); + mEditTopBar = view.findViewById(R.id.edit_list); + mTopBar = view.findViewById(R.id.top_bar); + mSelectAllButton = view.findViewById(R.id.select_all); + mEditButton = view.findViewById(R.id.edit); + mEditButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + actionMode = getActivity().startActionMode(actionModeCallback); +// mChatRoomsAdapter.setEditionMode(actionMode); +// mTopBar.setVisibility(View.GONE); +// mEditTopBar.setVisibility(View.VISIBLE); + } + }); + + mCancelButton = view.findViewById(R.id.cancel); +// mCancelButton.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View v) { +// actionMode.invalidate(); +// } +// }); + mDeselectAllButton = view.findViewById(R.id.deselect_all); + + mNewDiscussionButton = view.findViewById(R.id.new_discussion); mNewDiscussionButton.setOnClickListener(new View.OnClickListener() { @@ -148,9 +185,135 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene return view; } + @Override + public void onItemClicked(int position) { + if (actionMode != null) { + toggleSelection(position); + }else{ + ChatRoom room = (ChatRoom) mChatRoomsAdapter.getItem(position); + LinphoneActivity.instance().goToChat(room.getPeerAddress().asString()); + } + } + + @Override + public boolean onItemLongClicked(int position) { + if (actionMode == null) { + + actionMode = getActivity().startActionMode(actionModeCallback); + } + + toggleSelection(position); + + return true; + } + + private void toggleSelection(int position) { + mChatRoomsAdapter.toggleSelection(position); +// + int count = mChatRoomsAdapter.getSelectedItemCount(); + + if (count <= mChatRoomsAdapter.getItemCount()) { +// actionMode.finish(); + mDeselectAllButton.setVisibility(View.GONE); + mSelectAllButton.setVisibility(View.VISIBLE); + actionMode.invalidate(); + } else { + +// actionMode.setTitle(String.valueOf(count)); + mSelectAllButton.setVisibility(View.GONE); + mDeselectAllButton.setVisibility(View.VISIBLE); + actionMode.invalidate(); + } + } + + private class ActionModeCallback implements ActionMode.Callback { + @SuppressWarnings("unused") + private final String TAG = ActionModeCallback.class.getSimpleName(); + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + mTopBar.setVisibility(View.GONE); + mEditTopBar.setVisibility(View.VISIBLE); + + + for (Integer i = 0; i <= mChatRoomsAdapter.getItemCount(); i++) { + mChatRoomsAdapter.setEditionMode(mode); + } + mode.getMenuInflater().inflate (R.menu.edit_list_menu, menu); + + mCancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + actionMode.finish(); + } + }); + + + //Add all non-selected items to the selection + mSelectAllButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + for (Integer i = 0; i <= mChatRoomsAdapter.getItemCount(); i++) { + if (!mChatRoomsAdapter.isSelected(i)) { + toggleSelection(i); + } + } + } + }); + + return true; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { +// int cpt = 0; +// while (cpt <= mChatRoomsAdapter.getItemCount()) { +// mChatRoomsAdapter.setEditionMode(mode); +// cpt++; +// } + return false; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + switch (item.getItemId()) { + case R.id.delete_button: + // TODO: actually remove items + Log.d(TAG, "menu_remove"); + mode.finish(); + return true; + case R.id.cancel: + mode.finish(); + default: + return false; + } + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + mTopBar.setVisibility(View.VISIBLE); + mEditTopBar.setVisibility(View.GONE); + + mChatRoomsAdapter.clearSelection(); + actionMode = null; + mChatRoomsAdapter.setEditionMode(actionMode); + + } + + } + + + + + + + + + + private void refreshChatRoomsList() { mChatRoomsAdapter.refresh(); - mNoChatHistory.setVisibility(mChatRoomsAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); +// mNoChatHistory.setVisibility(mChatRoomsAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); } public void displayFirstChat() { @@ -232,7 +395,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter(); if (adapter != null) { - //adapter.notifyDataSetInvalidated(); +// adapter.notifyDataSetInvalidated(); } } } diff --git a/src/android/org/linphone/chat/ChatRoomsAdapter.java b/src/android/org/linphone/chat/ChatRoomsAdapter.java index 3775c1ee5..ff8a99d6b 100644 --- a/src/android/org/linphone/chat/ChatRoomsAdapter.java +++ b/src/android/org/linphone/chat/ChatRoomsAdapter.java @@ -25,6 +25,7 @@ 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; import android.view.View; import android.view.ViewGroup; @@ -66,7 +67,8 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter mRooms) { + public ChatRoomsAdapter(Context context, int itemResource, List mRooms, ChatRoomViewHolder.ClickListener clickListener) { public ChatRoomsAdapter(Context context, int itemResource, List mRooms) { super(); + this.editionMode = false; + this.clickListener = clickListener; this.mRooms = mRooms; this.mContext = context; this.itemResource = itemResource; @@ -182,10 +209,25 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter(Arrays.asList(LinphoneManager.getLc().getChatRooms())); Collections.sort(mRooms, new Comparator() { @@ -232,6 +274,7 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter Date: Mon, 28 May 2018 15:38:44 +0200 Subject: [PATCH 03/25] Conversion de Chatlist en RecyclerView terminee, selection + suppression terminee, desactivation de la TabBar+SideMenu durant le mode de selection --- AndroidManifest.xml | 4 +- build.gradle | 3 + .../src/org/linphone/tester/LogsActivity.java | 2 +- .../src/org/linphone/tester/MainActivity.java | 2 +- .../org/linphone/tester/SuitesActivity.java | 2 +- res/drawable/cancel_with_padding.xml | 11 + res/layout/chatlist.xml | 2 +- res/layout/context_bar.xml | 135 ++++++++++++ res/menu/edit_list_menu.xml | 76 +++---- res/values/styles.xml | 34 ++- .../linphone/activities/LinphoneActivity.java | 1 + .../assistant/CodecDownloaderFragment.java | 6 +- .../org/linphone/chat/ChatListFragment.java | 194 ++++++++++++------ .../org/linphone/chat/ChatRoomsAdapter.java | 87 +++++++- 14 files changed, 436 insertions(+), 123 deletions(-) create mode 100644 res/drawable/cancel_with_padding.xml create mode 100644 res/layout/context_bar.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index eb5f9c082..a12544872 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -64,7 +64,9 @@ android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:label="@string/app_name" - android:largeHeap="true"> + android:largeHeap="true" + > + + + + + + + \ No newline at end of file diff --git a/res/layout/chatlist.xml b/res/layout/chatlist.xml index 82ec2e2dc..083fa8c68 100644 --- a/res/layout/chatlist.xml +++ b/res/layout/chatlist.xml @@ -54,7 +54,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/menu/edit_list_menu.xml b/res/menu/edit_list_menu.xml index e6e24d02f..08925286a 100644 --- a/res/menu/edit_list_menu.xml +++ b/res/menu/edit_list_menu.xml @@ -1,58 +1,34 @@ + android:background="@color/colorA" + android:height="100dp" + android:layout_width="0dp" + android:layout_height="100dp" + android:visibility="gone" + > - - - - - - - - - - + android:icon="@drawable/delete" + app:showAsAction="ifRoom" + android:orderInCategory="1000" + android:title=""/> + + \ No newline at end of file diff --git a/res/values/styles.xml b/res/values/styles.xml index 9e99915ca..852f186e5 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -5,16 +5,48 @@ @drawable/fast_scroll @android:color/white @drawable/fast_scroll_preview + true + + + + + + + + - diff --git a/src/android/org/linphone/chat/ChatListFragment.java b/src/android/org/linphone/chat/ChatListFragment.java index da9903654..e7deec40d 100644 --- a/src/android/org/linphone/chat/ChatListFragment.java +++ b/src/android/org/linphone/chat/ChatListFragment.java @@ -62,11 +62,10 @@ import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST; public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ListSelectionHelper.DeleteListener { //public class ChatListFragment extends Fragment { - // private LayoutInflater mInflater; private ActionModeCallback actionModeCallback = new ActionModeCallback(); private ActionMode actionMode; - private LinearLayout mEditTopBar, mTabBar; + private LinearLayout mTabBar; private DrawerLayout mSideMenu; private ImageView mEditButton; private MenuItem mSelectAllButton, mDeselectAllButton, mDeleteButton; From dbba5ca413d353f17220f98fc2d88d6c93f6029b Mon Sep 17 00:00:00 2001 From: LuLe73 Date: Tue, 29 May 2018 15:50:56 +0200 Subject: [PATCH 06/25] Interface d origine conservee, ContextualActionBar definie a une hauteur de 1dp et background vide, inutilisee. L ActionMode fournit tout de meme ses services --- res/menu/edit_list_menu.xml | 6 +- res/values/styles.xml | 10 +- .../org/linphone/chat/ChatListFragment.java | 206 +++++++++--------- .../org/linphone/chat/ChatRoomsAdapter.java | 1 + 4 files changed, 117 insertions(+), 106 deletions(-) diff --git a/res/menu/edit_list_menu.xml b/res/menu/edit_list_menu.xml index 08925286a..1af3d9800 100644 --- a/res/menu/edit_list_menu.xml +++ b/res/menu/edit_list_menu.xml @@ -5,9 +5,9 @@ android:id="@+id/edit_list_menu" android:orientation="horizontal" android:background="@color/colorA" - android:height="100dp" + android:height="1dp" android:layout_width="0dp" - android:layout_height="100dp" + android:layout_height="1dp" android:visibility="gone" > @@ -27,7 +27,7 @@ android:id="@+id/deselect_all" android:icon="@drawable/deselect_all" app:showAsAction="ifRoom" - android:orderInCategory="200" + android:orderInCategory="100" android:visible="false" android:title=""/> diff --git a/res/values/styles.xml b/res/values/styles.xml index f934a3777..722162e74 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -10,14 +10,14 @@ diff --git a/src/android/org/linphone/chat/ChatListFragment.java b/src/android/org/linphone/chat/ChatListFragment.java index e7deec40d..0c7f9463c 100644 --- a/src/android/org/linphone/chat/ChatListFragment.java +++ b/src/android/org/linphone/chat/ChatListFragment.java @@ -25,22 +25,18 @@ import android.app.Fragment; import android.content.Context; import android.os.Bundle; import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.text.Layout; +import android.support.v7.widget.Toolbar; import android.view.ActionMode; -import android.support.v7.app.ActionBar; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; -//import android.widget.Toolbar; -import android.support.v7.widget.Toolbar; + import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.activities.LinphoneActivity; @@ -52,7 +48,6 @@ import org.linphone.core.ChatRoomListenerStub; import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.fragments.FragmentsAvailable; -import org.linphone.mediastream.Log; import java.util.ArrayList; import java.util.Arrays; @@ -60,15 +55,18 @@ import java.util.List; import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST; -public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ListSelectionHelper.DeleteListener { +//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 { private ActionModeCallback actionModeCallback = new ActionModeCallback(); private ActionMode actionMode; - private LinearLayout mTabBar; + private LinearLayout mTabBar, mEditTopBar, mTopBar; private DrawerLayout mSideMenu; - private ImageView mEditButton; - private MenuItem mSelectAllButton, mDeselectAllButton, mDeleteButton; + private ImageView mEditButton, mSelectAllButton, mDeselectAllButton,mDeleteButton, mCancelButton; private RecyclerView mChatRoomsList; private TextView mNoChatHistory; private ImageView mNewDiscussionButton, mBackToCallButton; @@ -121,18 +119,11 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene // mNoChatHistory = view.findViewById(R.id.noChatHistory); // mNoChatHistory.setVisibility(View.GONE); - //mEditTopBar = view.findViewById(R.id.edit_list_menu); - - - -// mTopBar = view.findViewById(R.id.top_bar); -// Toolbar toolbar = this.getActivity().findViewById(R.id.context_bar); - - - - -// mStatusBar = view.findViewById(R.id.status); - + mEditTopBar = view.findViewById(R.id.edit_list); + mTopBar = view.findViewById(R.id.top_bar); + mSelectAllButton = view.findViewById(R.id.select_all); + mDeselectAllButton = view.findViewById(R.id.deselect_all); + mDeleteButton= view.findViewById(R.id.delete); mEditButton = view.findViewById(R.id.edit); mEditButton.setOnClickListener(new View.OnClickListener() { @Override @@ -140,22 +131,18 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene actionMode = getActivity().startActionMode(actionModeCallback); - // getActivity().setActionBar(); - // mChatRoomsAdapter.setEditionMode(actionMode); -// mTopBar.setVisibility(View.GONE); -// mEditTopBar.setVisibility(View.VISIBLE); + } }); -// mCancelButton = view.findViewById(R.id.cancel); + mCancelButton = view.findViewById(R.id.cancel); // mCancelButton.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // actionMode.invalidate(); // } // }); -// mDeselectAllButton = view.findViewById(R.id.deselect_all); // mSelectAllButton = view.findViewById(R.id.select_all); @@ -240,19 +227,21 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene // int count = mChatRoomsAdapter.getSelectedItemCount(); - if (count < mChatRoomsAdapter.getItemCount()) { + if (count < mChatRoomsAdapter.getItemCount()/* || (mChatRoomsAdapter.getItemCount()==1 && count == 1)*/) { // actionMode.finish(); - mDeselectAllButton.setVisible(false); - mSelectAllButton.setVisible(true); + mDeselectAllButton.setVisibility(View.GONE); + mSelectAllButton.setVisibility(View.VISIBLE); - } else { + } /*else if (mChatRoomsAdapter.getItemCount()==1 && count == 1){ // actionMode.setTitle(String.valueOf(count)); - mDeselectAllButton.setVisible(true); - mSelectAllButton.setVisible(false); - + mSelectAllButton.setVisibility(View.VISIBLE); + mDeselectAllButton.setVisibility(View.GONE); + } */else{ + mSelectAllButton.setVisibility(View.GONE); + mDeselectAllButton.setVisibility(View.VISIBLE); } - getActivity().invalidateOptionsMenu(); + mChatRoomsAdapter.notifyItemChanged(position); actionMode.invalidate(); } @@ -263,39 +252,62 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { - //mTopBar.setVisibility(View.GONE); -// Toolbar contextBar = -// (RelativeLayout) view.findViewById(R.id.status); -// getActivity().getContext(); -// View v = View.inflate(R.layout.status, null); -// View view = (RelativeLayout)inflater.inflate(R.layout.chatlist, container, false); -// mStatusBar.setVisibility(View.VISIBLE); - mode.getMenuInflater().inflate (R.menu.edit_list_menu, menu); -// Menu contextBar = menu; - mDeselectAllButton = menu.findItem(R.id.deselect_all); - mSelectAllButton = menu.findItem(R.id.select_all); - mDeleteButton = menu.findItem(R.id.select_all); - mTabBar = (LinearLayout) getActivity().findViewById(R.id.footer); - mTabBar.setVisibility(View.INVISIBLE); - mSideMenu=(DrawerLayout) getActivity().findViewById(R.id.side_menu); - - mSideMenu.setDrawerLockMode(1); -// SlidingDrawer simpleSlidingDrawer = (SlidingDrawer) getActivity().findViewById(R.id.side_menu); // initiate the SlidingDrawer -// simpleSlidingDrawer.lock(); // lock the sliderDrawer so that touch event are disabled - -// menu.findItem(R.id.menu_search).getActionView(); -// LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); -// View tv= inflater.inflate(R.layout.context_bar, null); -// mode.setCustomView(tv); - -// (Toolbar) findViewById(R.id.status); - - - //mEditTopBar.setVisibility(View.VISIBLE); - + actionMode=mode; for (Integer i = 0; i <= mChatRoomsAdapter.getItemCount(); i++) { mChatRoomsAdapter.setEditionMode(mode); } + mTopBar.setVisibility(View.GONE); + mEditTopBar.setVisibility(View.VISIBLE); + +// mode.getMenuInflater().inflate (R.menu.edit_list_menu, menu); + mCancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + actionMode.finish(); + } + }); + mTabBar = (LinearLayout) getActivity().findViewById(R.id.footer); +// mTabBar.setVisibility(View.GONE); + mSideMenu=(DrawerLayout) getActivity().findViewById(R.id.side_menu); + + mSideMenu.setDrawerLockMode(1); + + //Add all non-selected items to the selection + mSelectAllButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) { + if (!mChatRoomsAdapter.isSelected(i)) { + toggleSelection(i); + } + } + } + }); + + //Remove all selected items from the selection + mDeselectAllButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) { + if (mChatRoomsAdapter.isSelected(i)) { + toggleSelection(i); + } + } + } + }); + + mDeleteButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mChatRoomsAdapter.removeItems(mChatRoomsAdapter.getSelectedItems()); + actionMode.finish(); + } + }); + + + + + return true; } @@ -315,30 +327,30 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { - case R.id.delete: - // TODO: actually remove items -// Log.d(TAG, "menu_remove"); - mChatRoomsAdapter.removeItems(mChatRoomsAdapter.getSelectedItems()); - mode.finish(); - return true; +// case R.id.delete: +// // TODO: actually remove items +//// Log.d(TAG, "menu_remove"); +// mChatRoomsAdapter.removeItems(mChatRoomsAdapter.getSelectedItems()); +// mode.finish(); +// return true; +// +// case R.id.select_all: +// //Add all non-selected items to the selection +// for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) { +// if (!mChatRoomsAdapter.isSelected(i)) { +// toggleSelection(i); +// } +// } +// +// return true; - case R.id.select_all: - //Add all non-selected items to the selection - for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) { - if (!mChatRoomsAdapter.isSelected(i)) { - toggleSelection(i); - } - } - - return true; - - case R.id.deselect_all: - for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) { - if (mChatRoomsAdapter.isSelected(i)) { - toggleSelection(i); - } - } - return true; +// case R.id.deselect_all: +// for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) { +// if (mChatRoomsAdapter.isSelected(i)) { +// toggleSelection(i); +// } +// } +// return true; // case R.id.cancel: // mode.finish(); default: @@ -351,9 +363,12 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene public void onDestroyActionMode(ActionMode mode) { mChatRoomsAdapter.clearSelection(); - mTabBar.setVisibility(View.VISIBLE); +// mTabBar.setVisibility(View.VISIBLE); + mTopBar.setVisibility(View.VISIBLE); + mEditTopBar.setVisibility(View.GONE); mSideMenu.setDrawerLockMode(0); + mChatRoomsAdapter.clearSelection(); actionMode = null; mChatRoomsAdapter.setEditionMode(actionMode); @@ -392,7 +407,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene if (LinphoneManager.getLc().getCallsNb() > 0) { mBackToCallButton.setVisibility(View.VISIBLE); } else { - mBackToCallButton.setVisibility(View.INVISIBLE); + mBackToCallButton.setVisibility(View.GONE); } if (LinphoneActivity.isInstanciated()) { @@ -417,13 +432,8 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene ContactsManager.removeContactsListener(this); - mChatRoomsAdapter.clearSelection(); -// mTabBar.setVisibility(View.VISIBLE); - actionMode = null; - mChatRoomsAdapter.setEditionMode(actionMode); - - mChatRoomsAdapter.clear(); +// mChatRoomsAdapter.clear(); super.onPause(); } diff --git a/src/android/org/linphone/chat/ChatRoomsAdapter.java b/src/android/org/linphone/chat/ChatRoomsAdapter.java index 2e052f00d..de5b7462e 100644 --- a/src/android/org/linphone/chat/ChatRoomsAdapter.java +++ b/src/android/org/linphone/chat/ChatRoomsAdapter.java @@ -302,6 +302,7 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter count && positions.get(count).equals(positions.get(count - 1) - 1)) { From 6faa06a6b01a7f881f99812671b6330ff7c4430d Mon Sep 17 00:00:00 2001 From: LuLe73 Date: Wed, 30 May 2018 13:14:13 +0200 Subject: [PATCH 07/25] Swipe des chatrooms + suppression implantes. A faire: nettoyage et commentaires --- res/layout/chatlist_cell.xml | 9 +- res/layout/chatlist_cell_active.xml | 125 ----------- .../org/linphone/chat/ChatListFragment.java | 111 +++++---- .../org/linphone/chat/ChatRoomsAdapter.java | 15 +- .../org/linphone/ui/SelectableAdapter.java | 69 +++++- .../org/linphone/ui/SwipeController.java | 211 ++++++++++++++++++ .../linphone/ui/SwipeControllerActions.java | 7 + 7 files changed, 375 insertions(+), 172 deletions(-) delete mode 100644 res/layout/chatlist_cell_active.xml create mode 100644 src/android/org/linphone/ui/SwipeController.java create mode 100644 src/android/org/linphone/ui/SwipeControllerActions.java diff --git a/res/layout/chatlist_cell.xml b/res/layout/chatlist_cell.xml index 99aefd1ff..0e27ce336 100644 --- a/res/layout/chatlist_cell.xml +++ b/res/layout/chatlist_cell.xml @@ -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"> + \ No newline at end of file diff --git a/res/layout/chatlist_cell_active.xml b/res/layout/chatlist_cell_active.xml deleted file mode 100644 index 6989dc64e..000000000 --- a/res/layout/chatlist_cell_active.xml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/android/org/linphone/chat/ChatListFragment.java b/src/android/org/linphone/chat/ChatListFragment.java index 0c7f9463c..8aa501101 100644 --- a/src/android/org/linphone/chat/ChatListFragment.java +++ b/src/android/org/linphone/chat/ChatListFragment.java @@ -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 mRooms; + public List 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() { diff --git a/src/android/org/linphone/chat/ChatRoomsAdapter.java b/src/android/org/linphone/chat/ChatRoomsAdapter.java index de5b7462e..1d7585e1e 100644 --- a/src/android/org/linphone/chat/ChatRoomsAdapter.java +++ b/src/android/org/linphone/chat/ChatRoomsAdapter.java @@ -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 { - 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 mRooms; + public List mRooms; private LayoutInflater mLayoutInflater; private Bitmap mDefaultBitmap, mDefaultGroupBitmap; private ChatRoomListenerStub mListener; @@ -202,7 +204,6 @@ public class ChatRoomsAdapter extends RecyclerView.Adapter mRooms) { public ChatRoomsAdapter(Context context, int itemResource, List mRooms, ChatRoomViewHolder.ClickListener clickListener) { - public ChatRoomsAdapter(Context context, int itemResource, List mRooms) { super(); this.editionMode = false; this.clickListener = clickListener; diff --git a/src/android/org/linphone/ui/SelectableAdapter.java b/src/android/org/linphone/ui/SelectableAdapter.java index 00d12b9fd..d07c548b7 100644 --- a/src/android/org/linphone/ui/SelectableAdapter.java +++ b/src/android/org/linphone/ui/SelectableAdapter.java @@ -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 extends RecyclerView.Adapter { + @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 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 getSelectedItems() { + List items = new ArrayList<>(selectedItems.size()); + for (int i = 0; i < selectedItems.size(); ++i) { + items.add(selectedItems.keyAt(i)); + } + return items; + } } diff --git a/src/android/org/linphone/ui/SwipeController.java b/src/android/org/linphone/ui/SwipeController.java new file mode 100644 index 000000000..2564cdfde --- /dev/null +++ b/src/android/org/linphone/ui/SwipeController.java @@ -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); + } + } + +} diff --git a/src/android/org/linphone/ui/SwipeControllerActions.java b/src/android/org/linphone/ui/SwipeControllerActions.java new file mode 100644 index 000000000..09cbe58b2 --- /dev/null +++ b/src/android/org/linphone/ui/SwipeControllerActions.java @@ -0,0 +1,7 @@ +package org.linphone.ui; + +public abstract class SwipeControllerActions { + public void onLeftClicked(int position) {} + + public void onRightClicked(int position) {} +} From 20c82860bd36fd4fa2755cd58d672dbb208ecebf Mon Sep 17 00:00:00 2001 From: LuLe73 Date: Wed, 30 May 2018 16:07:25 +0200 Subject: [PATCH 08/25] =?UTF-8?q?Commentaires=20et=20nettoyage=20effectu?= =?UTF-8?q?=C3=83e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- res/layout/chatlist.xml | 2 +- res/menu/edit_list_menu.xml | 34 --- res/values/styles.xml | 24 +- .../org/linphone/chat/ChatListFragment.java | 257 ++++++------------ .../org/linphone/chat/ChatRoomsAdapter.java | 252 ++++------------- .../org/linphone/ui/SwipeController.java | 4 + 6 files changed, 149 insertions(+), 424 deletions(-) delete mode 100644 res/menu/edit_list_menu.xml diff --git a/res/layout/chatlist.xml b/res/layout/chatlist.xml index 083fa8c68..82ec2e2dc 100644 --- a/res/layout/chatlist.xml +++ b/res/layout/chatlist.xml @@ -54,7 +54,7 @@ - + - - - - - - - - \ No newline at end of file diff --git a/res/values/styles.xml b/res/values/styles.xml index 722162e74..d2d979e8e 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -6,47 +6,29 @@ @android:color/white @drawable/fast_scroll_preview true - - - - - - +