From 59a522a4217cefc63d331ab422bc15322237dd57 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 25 Oct 2017 10:32:53 +0200 Subject: [PATCH] Started ChatEventsAdapter --- res/raw/linphonerc_factory | 4 + src/android/org/linphone/LinphoneManager.java | 3 + .../org/linphone/chat/ChatEventsAdapter.java | 228 +++++++++++++++++- .../org/linphone/chat/ChatFragment.java | 66 +---- .../org/linphone/chat/GroupChatFragment.java | 10 +- 5 files changed, 240 insertions(+), 71 deletions(-) diff --git a/res/raw/linphonerc_factory b/res/raw/linphonerc_factory index 310cd71c1..fddb47a4a 100644 --- a/res/raw/linphonerc_factory +++ b/res/raw/linphonerc_factory @@ -54,3 +54,7 @@ username_max_length=64 username_min_length=1 username_regex=^[a-z0-9_.\-]*$ xmlrpc_url=https://subscribe.linphone.org:444/wizard.php + +[server] +db_uri=/data/user/0/org.linphone/files/linphone.db +db_backend=sqlite3 diff --git a/src/android/org/linphone/LinphoneManager.java b/src/android/org/linphone/LinphoneManager.java index 33d3977c2..72d708eb4 100644 --- a/src/android/org/linphone/LinphoneManager.java +++ b/src/android/org/linphone/LinphoneManager.java @@ -228,6 +228,7 @@ public class LinphoneManager implements CoreListener, ChatMessageListener, Senso mChatDatabaseFile = basePath + "/linphone-history.db"; mCallLogDatabaseFile = basePath + "/linphone-log-history.db"; mFriendsDatabaseFile = basePath + "/linphone-friends.db"; + mLinphoneTestDb = basePath + "/linphone.db"; mErrorToneFile = basePath + "/error.wav"; mUserCertificatePath = basePath; @@ -258,6 +259,7 @@ public class LinphoneManager implements CoreListener, ChatMessageListener, Senso private final String mFriendsDatabaseFile; private final String mErrorToneFile; private final String mUserCertificatePath; + private final String mLinphoneTestDb; private byte[] mUploadingImage; private Timer mTimer; @@ -939,6 +941,7 @@ public class LinphoneManager implements CoreListener, ChatMessageListener, Senso copyIfNotExist(R.raw.lpconfig, mLPConfigXsd); copyFromPackage(R.raw.rootca, new File(mLinphoneRootCaFile).getName()); copyFromPackage(R.raw.assistant_create, new File(mDynamicConfigFile).getName()); + copyFromPackage(R.raw.linphone, new File(mLinphoneTestDb).getName()); } public void copyIfNotExist(int ressourceId, String target) throws IOException { diff --git a/src/android/org/linphone/chat/ChatEventsAdapter.java b/src/android/org/linphone/chat/ChatEventsAdapter.java index 9a64edbe0..d8e323f94 100644 --- a/src/android/org/linphone/chat/ChatEventsAdapter.java +++ b/src/android/org/linphone/chat/ChatEventsAdapter.java @@ -19,23 +19,58 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package org.linphone.chat; +import android.content.Context; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; +import android.widget.RelativeLayout; +import org.linphone.LinphoneManager; +import org.linphone.LinphoneUtils; import org.linphone.R; +import org.linphone.activities.LinphoneActivity; +import org.linphone.compatibility.Compatibility; +import org.linphone.contacts.ContactsManager; +import org.linphone.contacts.LinphoneContact; +import org.linphone.core.Address; import org.linphone.core.ChatMessage; +import org.linphone.core.Core; +import org.linphone.core.EventLog; -import java.util.ArrayList; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.List; +import java.util.regex.Pattern; public class ChatEventsAdapter extends BaseAdapter { - private ArrayList mHistory; + private Context mContext; + private List mHistory; + private List mParticipants; private LayoutInflater mLayoutInflater; - public ChatEventsAdapter(LayoutInflater inflater) { + public ChatEventsAdapter(Context context, LayoutInflater inflater, EventLog[] history, List participants) { + mContext = context; mLayoutInflater = inflater; - mHistory = new ArrayList<>(); //TODO + mHistory = Arrays.asList(history); + mParticipants = participants; + } + + public void updateHistory(EventLog[] history) { + mHistory = Arrays.asList(history); + notifyDataSetChanged(); + } + + public void addToHistory(EventLog log) { + mHistory.add(log); + notifyDataSetChanged(); + } + + public void setContacts(List participants) { + mParticipants = participants; } @Override @@ -64,11 +99,190 @@ public class ChatEventsAdapter extends BaseAdapter { view.setTag(holder); } - ChatMessage msg = (ChatMessage)getItem(i); - holder.messageId = msg.getMessageId(); + holder.eventLayout.setVisibility(View.GONE); + holder.bubbleLayout.setVisibility(View.GONE); + holder.delete.setVisibility(View.GONE); + holder.messageText.setVisibility(View.GONE); + holder.messageImage.setVisibility(View.GONE); + holder.fileExtensionLabel.setVisibility(View.GONE); + holder.fileNameLabel.setVisibility(View.GONE); + holder.fileTransferLayout.setVisibility(View.GONE); + holder.fileTransferProgressBar.setProgress(0); + holder.fileTransferAction.setEnabled(true); + holder.messageStatus.setVisibility(View.INVISIBLE); + holder.messageSendingInProgress.setVisibility(View.GONE); + holder.imdmLayout.setVisibility(View.INVISIBLE); - //TODO + EventLog event = (EventLog)getItem(i); + if (event.getType() == EventLog.Type.ConferenceChatMessage) { + holder.bubbleLayout.setVisibility(View.VISIBLE); + + ChatMessage message = null;//event.getChatMessage(); + holder.messageId = message.getMessageId(); + + RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + + ChatMessage.State status = message.getState(); + Address remoteSender = message.getFromAddress(); + String displayName; + + if (message.isOutgoing()) { + displayName = remoteSender.getDisplayName(); + + if (status == ChatMessage.State.InProgress) { + holder.messageSendingInProgress.setVisibility(View.VISIBLE); + } + + if (!message.isSecured() && LinphoneManager.getLc().limeEnabled() == Core.LimeState.Mandatory && status != ChatMessage.State.InProgress) { + holder.messageStatus.setVisibility(View.VISIBLE); + holder.messageStatus.setImageResource(R.drawable.chat_unsecure); + } + + if (status == ChatMessage.State.DeliveredToUser) { + holder.imdmLayout.setVisibility(View.VISIBLE); + holder.imdmIcon.setImageResource(R.drawable.chat_delivered); + holder.imdmLabel.setText(R.string.delivered); + holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorD)); + } else if (status == ChatMessage.State.Displayed) { + holder.imdmLayout.setVisibility(View.VISIBLE); + holder.imdmIcon.setImageResource(R.drawable.chat_read); + holder.imdmLabel.setText(R.string.displayed); + holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorK)); + } else if (status == ChatMessage.State.NotDelivered) { + holder.imdmLayout.setVisibility(View.VISIBLE); + holder.imdmIcon.setImageResource(R.drawable.chat_error); + holder.imdmLabel.setText(R.string.resend); + holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI)); + } + + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + layoutParams.setMargins(100, 10, 10, 10); + holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_outgoing); + Compatibility.setTextAppearance(holder.contactName, mContext, R.style.font3); + Compatibility.setTextAppearance(holder.fileTransferAction, mContext, R.style.font15); + holder.fileTransferAction.setBackgroundResource(R.drawable.resizable_confirm_delete_button); + holder.contactPictureMask.setImageResource(R.drawable.avatar_chat_mask_outgoing); + } else { + LinphoneContact contact = null; + for (LinphoneContact c : mParticipants) { + if (contact.hasAddress(remoteSender.asStringUriOnly())) { + contact = c; + break; + } + } + if (contact != null) { + if (contact.getFullName() != null) { + displayName = contact.getFullName(); + } else { + displayName = remoteSender.getDisplayName(); + if (displayName == null || displayName.isEmpty()) { + displayName = remoteSender.getUsername(); + } + } + + holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap()); + if (contact.hasPhoto()) { + LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri()); + } + } else { + displayName = remoteSender.getDisplayName(); + if (displayName == null || displayName.isEmpty()) { + displayName = remoteSender.getUsername(); + } + + holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap()); + } + + /*if (isEditMode) { + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + layoutParams.setMargins(100, 10, 10, 10); + }*/ + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); + layoutParams.setMargins(10, 10, 100, 10); + + holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_incoming); + Compatibility.setTextAppearance(holder.contactName, mContext, R.style.font9); + Compatibility.setTextAppearance(holder.fileTransferAction, mContext, R.style.font8); + holder.fileTransferAction.setBackgroundResource(R.drawable.resizable_assistant_button); + holder.contactPictureMask.setImageResource(R.drawable.avatar_chat_mask); + } + holder.contactName.setText(timestampToHumanDate(mContext, message.getTime()) + " - " + displayName); + + Spanned text = null; + String msg = message.getText(); + if (msg != null) { + text = getTextWithHttpLinks(msg); + holder.messageText.setText(text); + holder.messageText.setMovementMethod(LinkMovementMethod.getInstance()); + holder.messageText.setVisibility(View.VISIBLE); + } + + holder.bubbleLayout.setLayoutParams(layoutParams); + } else { + holder.eventLayout.setVisibility(View.VISIBLE); + //TODO + } return view; } + + private String timestampToHumanDate(Context context, long timestamp) { + try { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(timestamp); + + SimpleDateFormat dateFormat; + if (isToday(cal)) { + dateFormat = new SimpleDateFormat(context.getResources().getString(R.string.today_date_format)); + } else { + dateFormat = new SimpleDateFormat(context.getResources().getString(R.string.messages_date_format)); + } + + return dateFormat.format(cal.getTime()); + } catch (NumberFormatException nfe) { + return String.valueOf(timestamp); + } + } + + private boolean isToday(Calendar cal) { + return isSameDay(cal, Calendar.getInstance()); + } + + private boolean isSameDay(Calendar cal1, Calendar cal2) { + if (cal1 == null || cal2 == null) { + return false; + } + + return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && + cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && + cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR)); + } + + private Spanned getTextWithHttpLinks(String text) { + if (text.contains("<")) { + text = text.replace("<", "<"); + } + if (text.contains(">")) { + text = text.replace(">", ">"); + } + if (text.contains("\n")) { + text = text.replace("\n", "
"); + } + if (text.contains("http://")) { + int indexHttp = text.indexOf("http://"); + int indexFinHttp = text.indexOf(" ", indexHttp) == -1 ? text.length() : text.indexOf(" ", indexHttp); + String link = text.substring(indexHttp, indexFinHttp); + String linkWithoutScheme = link.replace("http://", ""); + text = text.replaceFirst(Pattern.quote(link), "" + linkWithoutScheme + ""); + } + if (text.contains("https://")) { + int indexHttp = text.indexOf("https://"); + int indexFinHttp = text.indexOf(" ", indexHttp) == -1 ? text.length() : text.indexOf(" ", indexHttp); + String link = text.substring(indexHttp, indexFinHttp); + String linkWithoutScheme = link.replace("https://", ""); + text = text.replaceFirst(Pattern.quote(link), "" + linkWithoutScheme + ""); + } + + return Compatibility.fromHtml(text); + } } diff --git a/src/android/org/linphone/chat/ChatFragment.java b/src/android/org/linphone/chat/ChatFragment.java index 33abaca3a..bac380ff4 100644 --- a/src/android/org/linphone/chat/ChatFragment.java +++ b/src/android/org/linphone/chat/ChatFragment.java @@ -1393,7 +1393,7 @@ public class ChatFragment extends Fragment implements OnClickListener, ChatMessa } else { holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap()); } - holder.contactName.setText(timestampToHumanDate(context, message.getTime()) + " - " + displayName); + //holder.contactName.setText(timestampToHumanDate(context, message.getTime()) + " - " + displayName); if (status == ChatMessage.State.InProgress) { holder.messageSendingInProgress.setVisibility(View.VISIBLE); @@ -1477,12 +1477,12 @@ public class ChatFragment extends Fragment implements OnClickListener, ChatMessa } else { Spanned text = null; String msg = message.getText(); - if (msg != null) { + /*if (msg != null) { text = getTextWithHttpLinks(msg); holder.messageText.setText(text); holder.messageText.setMovementMethod(LinkMovementMethod.getInstance()); holder.messageText.setVisibility(View.VISIBLE); - } + }*/ } if (message.isOutgoing()) { @@ -1643,66 +1643,6 @@ public class ChatFragment extends Fragment implements OnClickListener, ChatMessa return view; } - private String timestampToHumanDate(Context context, long timestamp) { - try { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(timestamp); - - SimpleDateFormat dateFormat; - if (isToday(cal)) { - dateFormat = new SimpleDateFormat(context.getResources().getString(R.string.today_date_format)); - } else { - dateFormat = new SimpleDateFormat(context.getResources().getString(R.string.messages_date_format)); - } - - return dateFormat.format(cal.getTime()); - } catch (NumberFormatException nfe) { - return String.valueOf(timestamp); - } - } - - private boolean isToday(Calendar cal) { - return isSameDay(cal, Calendar.getInstance()); - } - - private boolean isSameDay(Calendar cal1, Calendar cal2) { - if (cal1 == null || cal2 == null) { - return false; - } - - return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && - cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && - cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR)); - } - - private Spanned getTextWithHttpLinks(String text) { - if (text.contains("<")) { - text = text.replace("<", "<"); - } - if (text.contains(">")) { - text = text.replace(">", ">"); - } - if (text.contains("\n")) { - text = text.replace("\n", "
"); - } - if (text.contains("http://")) { - int indexHttp = text.indexOf("http://"); - int indexFinHttp = text.indexOf(" ", indexHttp) == -1 ? text.length() : text.indexOf(" ", indexHttp); - String link = text.substring(indexHttp, indexFinHttp); - String linkWithoutScheme = link.replace("http://", ""); - text = text.replaceFirst(Pattern.quote(link), "" + linkWithoutScheme + ""); - } - if (text.contains("https://")) { - int indexHttp = text.indexOf("https://"); - int indexFinHttp = text.indexOf(" ", indexHttp) == -1 ? text.length() : text.indexOf(" ", indexHttp); - String link = text.substring(indexHttp, indexFinHttp); - String linkWithoutScheme = link.replace("https://", ""); - text = text.replaceFirst(Pattern.quote(link), "" + linkWithoutScheme + ""); - } - - return Compatibility.fromHtml(text); - } - public void loadBitmap(String path, ImageView imageView) { if (cancelPotentialWork(path, imageView)) { if(LinphoneUtils.isExtensionImage(path)) diff --git a/src/android/org/linphone/chat/GroupChatFragment.java b/src/android/org/linphone/chat/GroupChatFragment.java index c5d2464de..cd7ad3ca9 100644 --- a/src/android/org/linphone/chat/GroupChatFragment.java +++ b/src/android/org/linphone/chat/GroupChatFragment.java @@ -267,6 +267,10 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con mParticipants.add(c); } } + + if (mMessagesAdapter != null) { + mMessagesAdapter.setContacts(mParticipants); + } } private void initChatRoom() { @@ -320,7 +324,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con } private void displayChatRoomHistory() { - mMessagesAdapter = new ChatEventsAdapter(mInflater); + mMessagesAdapter = new ChatEventsAdapter(getActivity(), mInflater, mChatRoom.getHistoryEvents(0), mParticipants); mChatEventsList.setAdapter(mMessagesAdapter); } @@ -373,6 +377,10 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con mMessageTextToSend.setText(""); } + private void scrollToBottom() { + mChatEventsList.setSelection(mMessagesAdapter.getCount() - 1); + } + @Override public void onUndecryptableMessageReceived(ChatRoom cr, ChatMessage msg) { final Address from = msg.getFromAddress();