diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6cf32ec1a..218bbcacb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -170,7 +170,8 @@
Do you want to delete selected conversation?
Do you want to delete selected message?
Remote is writing...
- %s is writing...
+ %s is writing...
+ %s are writing...
Small
Medium
Large
diff --git a/src/android/org/linphone/LinphoneManager.java b/src/android/org/linphone/LinphoneManager.java
index bee21190d..473cd1bd3 100644
--- a/src/android/org/linphone/LinphoneManager.java
+++ b/src/android/org/linphone/LinphoneManager.java
@@ -619,57 +619,7 @@ public class LinphoneManager implements CoreListener, ChatMessageListener, Senso
@Override
public void onUndecryptableMessageReceived(ChatRoom cr, ChatMessage message) {
- if (mServiceContext.getResources().getBoolean(R.bool.disable_chat)) {
- return;
- }
- final Address from = message.getFromAddress();
- String to = message.getToAddress().asString();
- try {
- final LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(from);
- if (LinphoneActivity.instance().isOnBackground()) {
- if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification)) {
- if (contact != null) {
- LinphoneService.instance().removedNotification(to, from.asStringUriOnly(), contact.getFullName()
- , getString(R.string.message_cant_be_decrypted_notif));
- } else {
- LinphoneService.instance().removedNotification(to, from.asStringUriOnly(), from.getUsername()
- , getString(R.string.message_cant_be_decrypted_notif));
- }
- }
- } else if (!mAreDisplayAlertMessage){
- mAreDisplayAlertMessage = true;
- final Dialog dialog = LinphoneActivity.instance().displayDialog(
- getString(R.string.message_cant_be_decrypted).replace("%s"
- , (contact != null) ? contact.getFullName() : from.getUsername()));
- Button delete = (Button) dialog.findViewById(R.id.delete_button);
- delete.setText(getString(R.string.call));
- Button cancel = (Button) dialog.findViewById(R.id.cancel);
- cancel.setText(getString(R.string.ok));
-
- delete.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- LinphoneManager.getInstance().newOutgoingCall(from.asStringUriOnly()
- , (contact != null) ? contact.getFullName() : from.getUsername());
- dialog.dismiss();
- LinphoneManager.getInstance().setAreDisplayAlertMessage(false);
- }
- });
-
- cancel.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- dialog.dismiss();
- LinphoneManager.getInstance().setAreDisplayAlertMessage(false);
- }
- });
- if(LinphoneManager.getLc().limeEnabled() == Core.LimeState.Mandatory)
- dialog.show();
- }
- } catch (Exception e) {
- Log.e(e);
- }
}
@Override
@@ -1839,7 +1789,7 @@ public class LinphoneManager implements CoreListener, ChatMessageListener, Senso
@Override
public void onChatRoomInstantiated(Core lc, ChatRoom cr) {
- cr.setListener(this);
+
}
@Override
diff --git a/src/android/org/linphone/chat/ChatBubbleViewHolder.java b/src/android/org/linphone/chat/ChatBubbleViewHolder.java
index f573b9a0a..d315eb070 100644
--- a/src/android/org/linphone/chat/ChatBubbleViewHolder.java
+++ b/src/android/org/linphone/chat/ChatBubbleViewHolder.java
@@ -29,13 +29,9 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import org.linphone.R;
-import org.linphone.core.Buffer;
-import org.linphone.core.ChatMessage;
-import org.linphone.core.ChatMessageListener;
-import org.linphone.core.Content;
-public class ChatBubbleViewHolder implements ChatMessageListener {
- public int id;
+public class ChatBubbleViewHolder {
+ public String messageId;
public LinearLayout eventLayout;
public TextView eventTime;
@@ -61,8 +57,6 @@ public class ChatBubbleViewHolder implements ChatMessageListener {
public TextView fileNameLabel;
public ChatBubbleViewHolder(View view) {
- id = view.getId();
-
eventLayout = view.findViewById(R.id.event);
eventTime = view.findViewById(R.id.event_date);
eventMessage = view.findViewById(R.id.event_text);
@@ -86,24 +80,4 @@ public class ChatBubbleViewHolder implements ChatMessageListener {
fileExtensionLabel = view.findViewById(R.id.file_extension);
fileNameLabel = view.findViewById(R.id.file_name);
}
-
- @Override
- public void onMsgStateChanged(ChatMessage msg, ChatMessage.State state) {
-
- }
-
- @Override
- public void onFileTransferRecv(ChatMessage msg, Content content, Buffer buffer) {
-
- }
-
- @Override
- public Buffer onFileTransferSend(ChatMessage message, Content content, int offset, int size) {
- return null;
- }
-
- @Override
- public void onFileTransferProgressIndication(ChatMessage msg, Content content, int offset, int total) {
- if (msg.getStorageId() == id) fileTransferProgressBar.setProgress(offset * 100 / total);
- }
}
\ No newline at end of file
diff --git a/src/android/org/linphone/chat/ChatEventsAdapter.java b/src/android/org/linphone/chat/ChatEventsAdapter.java
index d94803553..aac734da2 100644
--- a/src/android/org/linphone/chat/ChatEventsAdapter.java
+++ b/src/android/org/linphone/chat/ChatEventsAdapter.java
@@ -19,40 +19,55 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.chat;
-import android.content.Context;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import org.linphone.R;
import org.linphone.core.ChatMessage;
import java.util.ArrayList;
public class ChatEventsAdapter extends BaseAdapter {
private ArrayList mHistory;
- private Context mContext;
-
- public ChatEventsAdapter() {
+ private LayoutInflater mLayoutInflater;
+ public ChatEventsAdapter(LayoutInflater inflater) {
+ mLayoutInflater = inflater;
}
@Override
public int getCount() {
- return 0;
+ return mHistory.size();
}
@Override
public Object getItem(int i) {
- return null;
+ return mHistory.get(i);
}
@Override
public long getItemId(int i) {
- return 0;
+ return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
- return null;
+ ChatBubbleViewHolder holder;
+ if (view != null) {
+ holder = (ChatBubbleViewHolder) view.getTag();
+ } else {
+ view = mLayoutInflater.inflate(R.layout.chat_bubble, null);
+ holder = new ChatBubbleViewHolder(view);
+ view.setTag(holder);
+ }
+
+ ChatMessage msg = (ChatMessage)getItem(i);
+ holder.messageId = msg.getMessageId();
+
+ //TODO
+
+ return view;
}
}
diff --git a/src/android/org/linphone/chat/ChatFragment.java b/src/android/org/linphone/chat/ChatFragment.java
index 6faebd3e2..33abaca3a 100644
--- a/src/android/org/linphone/chat/ChatFragment.java
+++ b/src/android/org/linphone/chat/ChatFragment.java
@@ -1329,7 +1329,7 @@ public class ChatFragment extends Fragment implements OnClickListener, ChatMessa
view.setTag(holder);
}
- LinphoneManager.addListener(holder);
+ /*LinphoneManager.addListener(holder);
if (holder.id == message.getStorageId()) {
// Horrible workaround to not reload image on edit chat list
if (holder.messageImage.getTag() != null
@@ -1341,7 +1341,7 @@ public class ChatFragment extends Fragment implements OnClickListener, ChatMessa
} else {
holder.id = message.getStorageId();
}
- view.setId(holder.id);
+ view.setId(holder.id);*/
registerForContextMenu(view);
view.setOnClickListener(new OnClickListener() {
@Override
diff --git a/src/android/org/linphone/chat/GroupChatFragment.java b/src/android/org/linphone/chat/GroupChatFragment.java
index b4a213eba..22d35bf17 100644
--- a/src/android/org/linphone/chat/GroupChatFragment.java
+++ b/src/android/org/linphone/chat/GroupChatFragment.java
@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.chat;
+import android.app.Dialog;
import android.app.Fragment;
import android.os.Bundle;
import android.text.Editable;
@@ -26,19 +27,23 @@ import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.linphone.LinphoneManager;
+import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.activities.LinphoneActivity;
import org.linphone.contacts.ContactAddress;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
+import org.linphone.core.Buffer;
import org.linphone.core.ChatMessage;
+import org.linphone.core.ChatMessageListener;
import org.linphone.core.ChatRoom;
import org.linphone.core.ChatRoomListener;
import org.linphone.core.Content;
@@ -48,6 +53,8 @@ import org.linphone.core.Participant;
import java.util.ArrayList;
import java.util.List;
+import static org.linphone.fragments.FragmentsAvailable.CHAT;
+
public class GroupChatFragment extends Fragment implements ChatRoomListener {
private ImageView mBackButton, mCallButton, mBackToCallButton, mGroupInfosButton, mEditButton;
private ImageView mCancelEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton;
@@ -130,7 +137,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
mEditButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
-
+ //TODO
}
});
@@ -138,7 +145,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
mCancelEditButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
-
+ //TODO
}
});
@@ -146,7 +153,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
mSelectAllButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
-
+ //TODO
}
});
@@ -154,7 +161,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
mDeselectAllButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
-
+ //TODO
}
});
@@ -162,7 +169,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
mDeleteSelectionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
-
+ //TODO
}
});
@@ -172,7 +179,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
mAttachImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
-
+ //TODO
}
});
@@ -180,16 +187,14 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
mSendMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
-
+ sendMessage();
}
});
mMessageTextToSend = view.findViewById(R.id.message);
mMessageTextToSend.addTextChangedListener(new TextWatcher() {
@Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-
- }
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
@@ -200,9 +205,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
}
@Override
- public void afterTextChanged(Editable editable) {
-
- }
+ public void afterTextChanged(Editable editable) { }
});
mRemoteComposing = view.findViewById(R.id.remote_composing);
@@ -215,6 +218,11 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
@Override
public void onResume() {
super.onResume();
+
+ if (LinphoneActivity.isInstanciated()) {
+ LinphoneActivity.instance().selectMenu(CHAT);
+ }
+
initChatRoom();
displayChatRoomHeader();
displayChatRoomHistory();
@@ -282,12 +290,100 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
}
private void displayChatRoomHistory() {
- mMessagesAdapter = new ChatEventsAdapter();
+ mMessagesAdapter = new ChatEventsAdapter(mInflater);
+ //TODO
+ }
+
+ private void sendMessage() {
+ String text = mMessageTextToSend.getText().toString();
+ ChatMessage msg = mChatRoom.createMessage(text);
+ msg.setListener(new ChatMessageListener() {
+ @Override
+ public void onFileTransferRecv(ChatMessage message, Content content, Buffer buffer) {
+
+ }
+
+ @Override
+ public Buffer onFileTransferSend(ChatMessage message, Content content, int offset, int size) {
+ return null;
+ }
+
+ @Override
+ public void onFileTransferProgressIndication(ChatMessage message, Content content, int offset, int total) {
+ ChatBubbleViewHolder holder = (ChatBubbleViewHolder) message.getUserData();
+ if (holder != null && message.getMessageId().equals(holder.messageId)) {
+ holder.fileTransferProgressBar.setProgress(offset * 100 / total);
+ }
+ }
+
+ @Override
+ public void onMsgStateChanged(ChatMessage message, ChatMessage.State state) {
+ ChatBubbleViewHolder holder = (ChatBubbleViewHolder) message.getUserData();
+ if (holder != null && message.getMessageId().equals(holder.messageId)) {
+ if (state == ChatMessage.State.DeliveredToUser && message.isOutgoing()) {
+ holder.imdmLayout.setVisibility(View.VISIBLE);
+ holder.imdmIcon.setImageResource(R.drawable.message_delivered);
+ holder.imdmLabel.setText(R.string.delivered);
+ holder.imdmLabel.setTextColor(getResources().getColor(R.color.colorD));
+ } else if (state == ChatMessage.State.Displayed && message.isOutgoing()) {
+ holder.imdmLayout.setVisibility(View.VISIBLE);
+ holder.imdmIcon.setImageResource(R.drawable.message_read);
+ holder.imdmLabel.setText(R.string.displayed);
+ holder.imdmLabel.setTextColor(getResources().getColor(R.color.colorK));
+ } else if (state == ChatMessage.State.NotDelivered && message.isOutgoing()) {
+ holder.imdmLayout.setVisibility(View.VISIBLE);
+ holder.imdmIcon.setImageResource(R.drawable.message_undelivered);
+ holder.imdmLabel.setText(R.string.resend);
+ holder.imdmLabel.setTextColor(getResources().getColor(R.color.colorI));
+ }
+ }
+ }
+ });
+ msg.send();
+ mMessageTextToSend.setText("");
}
@Override
public void onUndecryptableMessageReceived(ChatRoom cr, ChatMessage msg) {
+ final Address from = msg.getFromAddress();
+ final LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(from);
+ if (LinphoneActivity.instance().isOnBackground()) {
+ if (!getResources().getBoolean(R.bool.disable_chat_message_notification)) {
+ String to = msg.getToAddress().asString();
+ if (contact != null) {
+ LinphoneService.instance().removedNotification(to, from.asStringUriOnly(),
+ contact.getFullName(), getString(R.string.message_cant_be_decrypted_notif));
+ } else {
+ LinphoneService.instance().removedNotification(to, from.asStringUriOnly(),
+ from.getUsername(), getString(R.string.message_cant_be_decrypted_notif));
+ }
+ }
+ } else if (LinphoneManager.getLc().limeEnabled() == Core.LimeState.Mandatory) {
+ final Dialog dialog = LinphoneActivity.instance().displayDialog(
+ getString(R.string.message_cant_be_decrypted)
+ .replace("%s", (contact != null) ? contact.getFullName() : from.getUsername()));
+ Button delete = dialog.findViewById(R.id.delete_button);
+ delete.setText(getString(R.string.call));
+ Button cancel = dialog.findViewById(R.id.cancel);
+ cancel.setText(getString(R.string.ok));
+ delete.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ LinphoneManager.getInstance().newOutgoingCall(from.asStringUriOnly()
+ , (contact != null) ? contact.getFullName() : from.getUsername());
+ dialog.dismiss();
+ }
+ });
+
+ cancel.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ dialog.dismiss();
+ }
+ });
+ dialog.show();
+ }
}
@Override
@@ -304,9 +400,61 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener {
@Override
public void onIsComposingReceived(ChatRoom cr, Address remoteAddr, boolean isComposing) {
- if (isComposing) {
- mRemoteComposing.setText(getString(R.string.remote_composing_2).replace("%s", remoteAddr.getDisplayName()));
+ if (cr.canHandleParticipants() && cr.getNbParticipants() > 2) {
+ ArrayList composing = new ArrayList<>();
+ for (Address a : cr.getComposingAddresses()) {
+ boolean found = false;
+ for (LinphoneContact c : mParticipants) {
+ if (c.hasAddress(a.asStringUriOnly())) {
+ composing.add(c.getFullName());
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ String displayName = a.getDisplayName();
+ if (displayName != null && !displayName.isEmpty()) {
+ composing.add(displayName);
+ } else {
+ composing.add(a.getUsername());
+ }
+ }
+ }
+
+ if (composing.size() == 1) {
+ mRemoteComposing.setText(getString(R.string.remote_composing_single).replace("%s", composing.get(0)));
+ mRemoteComposing.setVisibility(View.VISIBLE);
+ } else if (composing.size() > 2) {
+ StringBuilder remotes = new StringBuilder();
+ int i = 0;
+ for (String remote : composing) {
+ remotes.append(remote);
+ i++;
+ if (i != composing.size()) {
+ remotes.append(", ");
+ }
+ }
+ mRemoteComposing.setText(getString(R.string.remote_composing_multiple).replace("%s", remotes.toString()));
+ mRemoteComposing.setVisibility(View.VISIBLE);
+ } else {
+ mRemoteComposing.setVisibility(View.GONE);
+ }
+ } else {
+ if (isComposing) {
+ String displayName;
+ if (mParticipants.size() > 0) {
+ displayName = mParticipants.get(0).getFullName();
+ } else {
+ displayName = remoteAddr.getDisplayName();
+ if (displayName == null || displayName.isEmpty()) {
+ displayName = remoteAddr.getUsername();
+ }
+ }
+ mRemoteComposing.setText(getString(R.string.remote_composing_single).replace("%s", displayName));
+ mRemoteComposing.setVisibility(View.VISIBLE);
+ } else {
+ mRemoteComposing.setVisibility(View.GONE);
+ }
}
- mRemoteComposing.setVisibility(isComposing ? View.VISIBLE : View.GONE);
}
}