From 1fc73e18feec6cc09e1f9b657fa0ca87c84eb7ff Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Tue, 5 Sep 2017 10:58:45 +0200 Subject: [PATCH] First change for groupe chat --- prepare.py | 2 +- .../org/linphone/ChatCreationFragment.java | 151 ++++++++++++++ src/android/org/linphone/ChatFragment.java | 137 +------------ src/android/org/linphone/ContactAddress.java | 45 ++++ .../org/linphone/ContactsListFragment.java | 2 +- .../org/linphone/FragmentsAvailable.java | 9 +- .../org/linphone/LinphoneActivity.java | 51 +++-- .../linphone/SearchContactsListAdapter.java | 194 ++++++++++++++++++ 8 files changed, 434 insertions(+), 157 deletions(-) create mode 100644 src/android/org/linphone/ChatCreationFragment.java create mode 100644 src/android/org/linphone/ContactAddress.java create mode 100644 src/android/org/linphone/SearchContactsListAdapter.java diff --git a/prepare.py b/prepare.py index 760ea3f4d..a59a4649f 100755 --- a/prepare.py +++ b/prepare.py @@ -96,7 +96,7 @@ class AndroidPreparator(prepare.Preparator): def __init__(self, targets=android_targets): prepare.Preparator.__init__(self, targets, default_targets=['armv7', 'arm64', 'x86']) self.min_supported_ndk = 10 - self.max_supported_ndk = 15 + self.max_supported_ndk = 16 self.unsupported_ndk_version = None self.min_cmake_version = "3.7" self.release_with_debug_info = True diff --git a/src/android/org/linphone/ChatCreationFragment.java b/src/android/org/linphone/ChatCreationFragment.java new file mode 100644 index 000000000..85943b19a --- /dev/null +++ b/src/android/org/linphone/ChatCreationFragment.java @@ -0,0 +1,151 @@ +/* +ChatCreationFragment.java +Copyright (C) 2017 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package org.linphone; + +import android.app.Fragment; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +/** + * Created by Erwan Croze. + */ + +public class ChatCreationFragment extends Fragment implements View.OnClickListener, AdapterView.OnItemClickListener, ContactsUpdatedListener { + private LayoutInflater mInflater; + private ListView contactsList; + private TextView noSipContact, noContact; + private ImageView allContacts, linphoneContacts; + private boolean onlyDisplayLinphoneContacts; + private View allContactsSelected, linphoneContactsSelected; + private ImageView clearSearchField; + private EditText searchField; + private ProgressBar contactsFetchInProgress; + private SearchContactsListAdapter searchAdapter; + private ImageView back; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + mInflater = inflater; + View view = inflater.inflate(R.layout.create_chat, container, false); + + noSipContact = (TextView) view.findViewById(R.id.noSipContact); + noContact = (TextView) view.findViewById(R.id.noContact); + + contactsList = (ListView) view.findViewById(R.id.contactsList); + contactsList.setOnItemClickListener(this); + + allContacts = (ImageView) view.findViewById(R.id.all_contacts); + allContacts.setOnClickListener(this); + + linphoneContacts = (ImageView) view.findViewById(R.id.linphone_contacts); + linphoneContacts.setOnClickListener(this); + + allContactsSelected = view.findViewById(R.id.all_contacts_select); + linphoneContactsSelected = view.findViewById(R.id.linphone_contacts_select); + + allContacts.setEnabled(onlyDisplayLinphoneContacts); + linphoneContacts.setEnabled(!allContacts.isEnabled()); + + back = (ImageView) view.findViewById(R.id.back); + back.setOnClickListener(this); + + clearSearchField = (ImageView) view.findViewById(R.id.clearSearchField); + clearSearchField.setOnClickListener(this); + + contactsFetchInProgress = (ProgressBar) view.findViewById(R.id.contactsFetchInProgress); + contactsFetchInProgress.setVisibility(View.VISIBLE); + + searchAdapter = new SearchContactsListAdapter(null, mInflater, contactsFetchInProgress); + contactsList.setAdapter(searchAdapter); + + searchField = (EditText) view.findViewById(R.id.searchField); + searchField.addTextChangedListener(new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + + } + + @Override + public void afterTextChanged(Editable s) { + searchAdapter.searchContacts(searchField.getText().toString(), contactsList); + } + }); + + return view; + } + + public ChatCreationFragment() { + } + + @Override + public void onClick(View view) { + int id = view.getId(); + if (id == R.id.all_contacts) { + searchAdapter.setOnlySipContact(onlyDisplayLinphoneContacts = false); + allContactsSelected.setVisibility(View.VISIBLE); + allContacts.setEnabled(false); + linphoneContacts.setEnabled(true); + linphoneContactsSelected.setVisibility(View.INVISIBLE); + searchAdapter.setContactsList(null); + searchAdapter.searchContacts(searchField.getText().toString(), contactsList); + } else if (id == R.id.linphone_contacts) { + searchAdapter.setOnlySipContact(true); + linphoneContactsSelected.setVisibility(View.VISIBLE); + linphoneContacts.setEnabled(false); + allContacts.setEnabled(onlyDisplayLinphoneContacts = true); + allContactsSelected.setVisibility(View.INVISIBLE); + searchAdapter.setContactsList(null); + searchAdapter.searchContacts(searchField.getText().toString(), contactsList); + } else if (id == R.id.back) { + getFragmentManager().popBackStackImmediate(); + } else if (id == R.id.next) { + //TODO aller selon le nombre de selectionner en chat ou en groupe + } else if (id == R.id.clearSearchField) { + searchField.setText(""); + searchAdapter.searchContacts("", contactsList); + } + } + + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + + } + + @Override + public void onContactsUpdated() { + + } +} diff --git a/src/android/org/linphone/ChatFragment.java b/src/android/org/linphone/ChatFragment.java index 67534f69a..7e842db45 100644 --- a/src/android/org/linphone/ChatFragment.java +++ b/src/android/org/linphone/ChatFragment.java @@ -1,7 +1,7 @@ package org.linphone; /* ChatFragment.java -Copyright (C) 2015 Belledonne Communications, Grenoble, France +Copyright (C) 2017 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -1206,7 +1206,13 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC startCall.setVisibility(View.INVISIBLE); contactName.setVisibility(View.INVISIBLE); resultContactsSearch.setVisibility(View.VISIBLE); - searchAdapter = new SearchContactsListAdapter(null); + searchAdapter = new SearchContactsListAdapter(null, inflater, null); + searchAdapter.setListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + exitNewConversationMode((String)view.getTag(R.id.contact_search_name)); + } + }); resultContactsSearch.setAdapter(searchAdapter); searchContactField.setVisibility(View.VISIBLE); searchContactField.setText(""); @@ -1221,43 +1227,11 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC @Override public void afterTextChanged(Editable s) { - searchContacts(searchContactField.getText().toString()); + searchAdapter.searchContacts(searchContactField.getText().toString(), resultContactsSearch); } }); } - private class ContactAddress { - LinphoneContact contact; - String address; - - private ContactAddress(LinphoneContact c, String a){ - this.contact = c; - this.address = a; - } - } - - private void searchContacts(String search) { - if (search == null || search.length() == 0) { - resultContactsSearch.setAdapter(new SearchContactsListAdapter(null)); - return; - } - - List result = new ArrayList(); - if(search != null) { - for (ContactAddress c : searchAdapter.contacts) { - String address = c.address; - if (address.startsWith("sip:")) address = address.substring(4); - if (c.contact.getFullName() != null && c.contact.getFullName().toLowerCase(Locale.getDefault()).startsWith(search.toLowerCase(Locale.getDefault())) - || address.toLowerCase(Locale.getDefault()).startsWith(search.toLowerCase(Locale.getDefault()))) { - result.add(c); - } - } - } - - resultContactsSearch.setAdapter(new SearchContactsListAdapter(result)); - searchAdapter.notifyDataSetChanged(); - } - class ChatMessageAdapter extends BaseAdapter { private class ViewHolder implements LinphoneChatMessage.LinphoneChatMessageListener { public int id; @@ -1923,99 +1897,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } } - class SearchContactsListAdapter extends BaseAdapter { - private class ViewHolder { - public TextView name; - public TextView address; - - public ViewHolder(View view) { - name = (TextView) view.findViewById(R.id.contact_name); - address = (TextView) view.findViewById(R.id.contact_address); - } - } - - private List contacts; - private LayoutInflater mInflater; - - SearchContactsListAdapter(List contactsList) { - mInflater = inflater; - if (contactsList == null) { - contacts = getContactsList(); - } else { - contacts = contactsList; - } - } - - public List getContactsList() { - List list = new ArrayList(); - if(ContactsManager.getInstance().hasContacts()) { - for (LinphoneContact con : ContactsManager.getInstance().getContacts()) { - for (LinphoneNumberOrAddress noa : con.getNumbersOrAddresses()) { - String value = noa.getValue(); - // Fix for sip:username compatibility issue - if (value.startsWith("sip:") && !value.contains("@")) { - value = value.substring(4); - value = LinphoneUtils.getFullAddressFromUsername(value); - } - list.add(new ContactAddress(con, value)); - } - } - } - return list; - } - - public int getCount() { - return contacts.size(); - } - - public ContactAddress getItem(int position) { - if (contacts == null || position >= contacts.size()) { - contacts = getContactsList(); - return contacts.get(position); - } else { - return contacts.get(position); - } - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - View view = null; - ContactAddress contact; - ViewHolder holder = null; - - do { - contact = getItem(position); - } while (contact == null); - - if (convertView != null) { - view = convertView; - holder = (ViewHolder) view.getTag(); - } else { - view = mInflater.inflate(R.layout.search_contact_cell, parent, false); - holder = new ViewHolder(view); - view.setTag(holder); - } - - final String a = contact.address; - LinphoneContact c = contact.contact; - - holder.name.setText(c.getFullName()); - holder.address.setText(a); - - view.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - exitNewConversationMode(a); - } - }); - - return view; - } - } - //LinphoneChatMessage Listener @Override public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) { diff --git a/src/android/org/linphone/ContactAddress.java b/src/android/org/linphone/ContactAddress.java new file mode 100644 index 000000000..41f3cb092 --- /dev/null +++ b/src/android/org/linphone/ContactAddress.java @@ -0,0 +1,45 @@ +package org.linphone; + +/* +ContactAddress.java +Copyright (C) 2017 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +public class ContactAddress { + LinphoneContact contact; + String address; + boolean isLinphoneContact; + boolean isSelect = false; + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + + public boolean isLinphoneContact() { + return isLinphoneContact; + } + + public ContactAddress(LinphoneContact c, String a, boolean isLC){ + this.contact = c; + this.address = a; + this.isLinphoneContact = isLC; + } +} diff --git a/src/android/org/linphone/ContactsListFragment.java b/src/android/org/linphone/ContactsListFragment.java index dbab611d7..42576845b 100644 --- a/src/android/org/linphone/ContactsListFragment.java +++ b/src/android/org/linphone/ContactsListFragment.java @@ -1,6 +1,6 @@ /* ContactsListFragment.java -Copyright (C) 2015 Belledonne Communications, Grenoble, France +Copyright (C) 2017 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/src/android/org/linphone/FragmentsAvailable.java b/src/android/org/linphone/FragmentsAvailable.java index cebeabcb8..82c13a95a 100644 --- a/src/android/org/linphone/FragmentsAvailable.java +++ b/src/android/org/linphone/FragmentsAvailable.java @@ -33,7 +33,8 @@ public enum FragmentsAvailable { ACCOUNT_SETTINGS, SETTINGS, CHAT_LIST, - CHAT; + CHAT, + CREATE_CHAT; public boolean shouldAnimate() { return true; @@ -72,6 +73,9 @@ public enum FragmentsAvailable { case CHAT: return CHAT_LIST.isRightOf(fragment) || fragment == CHAT_LIST; + case CREATE_CHAT: + return CHAT_LIST.isRightOf(fragment) || fragment == CHAT_LIST; + default: return false; } @@ -91,6 +95,9 @@ public enum FragmentsAvailable { case CHAT: return fragment == CHAT_LIST || fragment == CHAT; + case CREATE_CHAT: + return fragment == CHAT_LIST || fragment == CREATE_CHAT; + default: return false; } diff --git a/src/android/org/linphone/LinphoneActivity.java b/src/android/org/linphone/LinphoneActivity.java index 2686fbbcd..d07e423aa 100644 --- a/src/android/org/linphone/LinphoneActivity.java +++ b/src/android/org/linphone/LinphoneActivity.java @@ -404,6 +404,9 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick case CHAT: fragment = new ChatFragment(); break; + case CREATE_CHAT: + fragment = new ChatCreationFragment(); + break; default: break; } @@ -645,6 +648,25 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick return count; } + private void displayChat(String sipUri, String message, String fileUri, String pictureUri, String thumbnailUri, String displayName, LinphoneAddress lAddress) { + Bundle extras = new Bundle(); + extras.putString("SipUri", sipUri); + if(message != null) + extras.putString("messageDraft", message); + if(fileUri != null) + extras.putString("fileSharedUri", fileUri); + if (sipUri != null && lAddress.getDisplayName() != null) { + extras.putString("DisplayName", displayName); + extras.putString("PictureUri", pictureUri); + extras.putString("ThumbnailUri", thumbnailUri); + } + if(sipUri == null && message == null && fileUri == null) { + changeCurrentFragment(FragmentsAvailable.CREATE_CHAT, extras); + } else { + changeCurrentFragment(FragmentsAvailable.CHAT, extras); + } + } + public void displayChat(String sipUri, String message, String fileUri) { if (getResources().getBoolean(R.bool.disable_chat)) { return; @@ -678,37 +700,13 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick ChatFragment chatFragment = (ChatFragment) fragment2; chatFragment.changeDisplayedChat(sipUri, displayName, pictureUri, message, fileUri); } else { - Bundle extras = new Bundle(); - extras.putString("SipUri", sipUri); - if(message != null) - extras.putString("messageDraft", message); - if(fileUri != null) - extras.putString("fileSharedUri", fileUri); - if (sipUri != null && lAddress.getDisplayName() != null) { - extras.putString("DisplayName", displayName); - extras.putString("PictureUri", pictureUri); - extras.putString("ThumbnailUri", thumbnailUri); - } - changeCurrentFragment(FragmentsAvailable.CHAT, extras); + displayChat(sipUri, message, fileUri, pictureUri, thumbnailUri, displayName, lAddress); } } else { if(isTablet()){ changeCurrentFragment(FragmentsAvailable.CHAT_LIST, null); - //displayChat(sipUri, message, fileUri); } else { - Bundle extras = new Bundle(); - if(sipUri != null || sipUri != "") - extras.putString("SipUri", sipUri); - if(message != null) - extras.putString("messageDraft", message); - if(fileUri != null) - extras.putString("fileSharedUri", fileUri); - if (sipUri != null && lAddress.getDisplayName() != null) { - extras.putString("DisplayName", displayName); - extras.putString("PictureUri", pictureUri); - extras.putString("ThumbnailUri", thumbnailUri); - } - changeCurrentFragment(FragmentsAvailable.CHAT, extras); + displayChat(sipUri, message, fileUri, pictureUri, thumbnailUri, displayName, lAddress); } } @@ -788,6 +786,7 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick hideTabBar(true); break; case CHAT_LIST: + case CREATE_CHAT: case CHAT: chat_selected.setVisibility(View.VISIBLE); break; diff --git a/src/android/org/linphone/SearchContactsListAdapter.java b/src/android/org/linphone/SearchContactsListAdapter.java new file mode 100644 index 000000000..238812a37 --- /dev/null +++ b/src/android/org/linphone/SearchContactsListAdapter.java @@ -0,0 +1,194 @@ +package org.linphone; + +/* +SearchContactsListAdapter.java +Copyright (C) 2017 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.media.Image; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Created by Erwan Croze. + */ + +public class SearchContactsListAdapter extends BaseAdapter { + private class ViewHolder { + public TextView name; + public TextView address; + public ImageView linphoneContact; + public ImageView isSelect; + + public ViewHolder(View view) { + name = (TextView) view.findViewById(R.id.contact_name); + address = (TextView) view.findViewById(R.id.contact_address); + linphoneContact = (ImageView) view.findViewById(R.id.contact_linphone); + isSelect = (ImageView) view.findViewById(R.id.contact_is_select); + } + } + + public List getContacts() { + return contacts; + } + + private List contacts; + private LayoutInflater mInflater; + private ProgressBar progressBar; + private boolean mOnlySipContact = false; + + public void setOnlySipContact(boolean enable) { + mOnlySipContact = enable; + } + + public void setListener(View.OnClickListener listener) { + this.listener = listener; + } + + private View.OnClickListener listener; + + SearchContactsListAdapter(List contactsList, LayoutInflater inflater, ProgressBar pB) { + mInflater = inflater; + progressBar = pB; + setContactsList(contactsList); + } + + public void setContactsList(List contactsList) { + if (contactsList == null) { + contacts = getContactsList(); + if (contacts.size() > 0 && progressBar != null) + progressBar.setVisibility(View.GONE); + } else { + contacts = contactsList; + } + } + + public List getContactsList() { + List list = new ArrayList(); + if(ContactsManager.getInstance().hasContacts()) { + for (LinphoneContact con : (mOnlySipContact) + ? ContactsManager.getInstance().getSIPContacts() : ContactsManager.getInstance().getContacts()) { + for (LinphoneNumberOrAddress noa : con.getNumbersOrAddresses()) { + String value = noa.getValue(); + // Fix for sip:username compatibility issue + if (value.startsWith("sip:") && !value.contains("@")) { + value = value.substring(4); + value = LinphoneUtils.getFullAddressFromUsername(value); + } + list.add(new ContactAddress(con, value, con.isInLinphoneFriendList())); + } + } + } + return list; + } + + public int getCount() { + return contacts.size(); + } + + public ContactAddress getItem(int position) { + if (contacts == null || position >= contacts.size()) { + contacts = getContactsList(); + return contacts.get(position); + } else { + return contacts.get(position); + } + } + + public long getItemId(int position) { + return position; + } + + public void searchContacts(String search, ListView resultContactsSearch) { + if (search == null || search.length() == 0) { + setContactsList(null); + resultContactsSearch.setAdapter(this); + return; + } + + List result = new ArrayList(); + if(search != null) { + for (ContactAddress c : getContacts()) { + String address = c.address; + if (address.startsWith("sip:")) address = address.substring(4); + if (c.contact.getFullName() != null && c.contact.getFullName().toLowerCase(Locale.getDefault()).startsWith(search.toLowerCase(Locale.getDefault())) + || address.toLowerCase(Locale.getDefault()).startsWith(search.toLowerCase(Locale.getDefault()))) { + result.add(c); + } + } + } + + setContactsList(result); + resultContactsSearch.setAdapter(this); + this.notifyDataSetChanged(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View view; + ViewHolder holder; + ContactAddress contact; + + do { + contact = getItem(position); + } while (contact == null); + + if (convertView != null) { + view = convertView; + holder = (ViewHolder) view.getTag(); + } else { + view = mInflater.inflate(R.layout.search_contact_cell, parent, false); + holder = new ViewHolder(view); + view.setTag(holder); + } + + final String a = contact.address; + LinphoneContact c = contact.contact; + + holder.name.setText(c.getFullName()); + holder.address.setText(a); + if (holder.linphoneContact != null) { + if (contact.isLinphoneContact()) { + holder.linphoneContact.setVisibility(View.VISIBLE); + } else { + holder.linphoneContact.setVisibility(View.GONE); + } + } + if (holder.isSelect != null) { + if (contact.isSelect()) { + holder.isSelect.setImageResource(R.drawable.check_selected); + } else { + holder.isSelect.setImageResource(R.drawable.check_unselected); + } + } + view.setTag(R.id.contact_search_name, a); + view.setOnClickListener(listener); + + return view; + } +} +