Started GroupChatFragment, in standby until Events are wrapped

This commit is contained in:
Sylvain Berfini 2017-10-23 13:50:55 +02:00
parent 566effbc50
commit cc26517006
9 changed files with 444 additions and 101 deletions

View file

@ -22,8 +22,7 @@
android:id="@+id/event_date" android:id="@+id/event_date"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textStyle="italic" android:textStyle="italic"/>
android:text="Aujourd'hui"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -33,8 +32,7 @@
<TextView <TextView
android:id="@+id/event_text" android:id="@+id/event_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"/>
android:text="Machin à ajouté Machine"/>
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -170,6 +170,7 @@
<string name="delete_conversation">Do you want to delete selected conversation?</string> <string name="delete_conversation">Do you want to delete selected conversation?</string>
<string name="delete_message">Do you want to delete selected message?</string> <string name="delete_message">Do you want to delete selected message?</string>
<string name="remote_composing">Remote is writing...</string> <string name="remote_composing">Remote is writing...</string>
<string name="remote_composing_2">%s is writing...</string>
<string name="share_picture_size_small">Small</string> <string name="share_picture_size_small">Small</string>
<string name="share_picture_size_medium">Medium</string> <string name="share_picture_size_medium">Medium</string>
<string name="share_picture_size_large">Large</string> <string name="share_picture_size_large">Large</string>

View file

@ -711,12 +711,7 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
if(sipUri == null && message == null && fileUri == null) { if(sipUri == null && message == null && fileUri == null) {
changeCurrentFragment(FragmentsAvailable.CREATE_CHAT, extras); changeCurrentFragment(FragmentsAvailable.CREATE_CHAT, extras);
} else { } else {
ChatRoom room = LinphoneManager.getLc().getChatRoom(lAddress); changeCurrentFragment(FragmentsAvailable.GROUP_CHAT, extras);
if (room.canHandleParticipants()) {
changeCurrentFragment(FragmentsAvailable.GROUP_CHAT, extras);
} else {
changeCurrentFragment(FragmentsAvailable.CHAT, extras);
}
} }
} }

View file

@ -0,0 +1,109 @@
/*
ChatBubbleViewHolder.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.chat;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
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 LinearLayout eventLayout;
public TextView eventTime;
public TextView eventMessage;
public RelativeLayout bubbleLayout;
public CheckBox delete;
public LinearLayout background;
public ImageView contactPicture;
public TextView contactName;
public TextView messageText;
public ImageView messageImage;
public RelativeLayout fileTransferLayout;
public ProgressBar fileTransferProgressBar;
public Button fileTransferAction;
public ImageView messageStatus;
public ProgressBar messageSendingInProgress;
public ImageView contactPictureMask;
public LinearLayout imdmLayout;
public ImageView imdmIcon;
public TextView imdmLabel;
public TextView fileExtensionLabel;
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);
bubbleLayout = (RelativeLayout) view.findViewById(R.id.bubble);
delete = (CheckBox) view.findViewById(R.id.delete_message);
background = (LinearLayout) view.findViewById(R.id.background);
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
contactName = (TextView) view.findViewById(R.id.contact_header);
messageText = (TextView) view.findViewById(R.id.message);
messageImage = (ImageView) view.findViewById(R.id.image);
fileTransferLayout = (RelativeLayout) view.findViewById(R.id.file_transfer_layout);
fileTransferProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
fileTransferAction = (Button) view.findViewById(R.id.file_transfer_action);
messageStatus = (ImageView) view.findViewById(R.id.status);
messageSendingInProgress = (ProgressBar) view.findViewById(R.id.inprogress);
contactPictureMask = (ImageView) view.findViewById(R.id.mask);
imdmLayout = (LinearLayout) view.findViewById(R.id.imdmLayout);
imdmIcon = (ImageView) view.findViewById(R.id.imdmIcon);
imdmLabel = (TextView) view.findViewById(R.id.imdmText);
fileExtensionLabel = (TextView) view.findViewById(R.id.file_extension);
fileNameLabel = (TextView) 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);
}
}

View file

@ -0,0 +1,58 @@
/*
GroupChatFragment.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.chat;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import org.linphone.core.ChatMessage;
import java.util.ArrayList;
public class ChatEventsAdapter extends BaseAdapter {
private ArrayList<ChatMessage> mHistory;
private Context mContext;
public ChatEventsAdapter() {
}
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
return null;
}
}

View file

@ -1263,72 +1263,7 @@ public class ChatFragment extends Fragment implements OnClickListener, ChatMessa
} }
class ChatMessageAdapter extends BaseAdapter { class ChatMessageAdapter extends BaseAdapter {
private class ViewHolder implements ChatMessageListener { private
public int id;
public LinearLayout eventLayout;
public RelativeLayout bubbleLayout;
public CheckBox delete;
public LinearLayout background;
public ImageView contactPicture;
public TextView contactName;
public TextView messageText;
public ImageView messageImage;
public RelativeLayout fileTransferLayout;
public ProgressBar fileTransferProgressBar;
public Button fileTransferAction;
public ImageView messageStatus;
public ProgressBar messageSendingInProgress;
public ImageView contactPictureMask;
public LinearLayout imdmLayout;
public ImageView imdmIcon;
public TextView imdmLabel;
public TextView fileExtensionLabel;
public TextView fileNameLabel;
public ViewHolder(View view) {
id = view.getId();
eventLayout = (LinearLayout) view.findViewById(R.id.event);
bubbleLayout = (RelativeLayout) view.findViewById(R.id.bubble);
delete = (CheckBox) view.findViewById(R.id.delete_message);
background = (LinearLayout) view.findViewById(R.id.background);
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
contactName = (TextView) view.findViewById(R.id.contact_header);
messageText = (TextView) view.findViewById(R.id.message);
messageImage = (ImageView) view.findViewById(R.id.image);
fileTransferLayout = (RelativeLayout) view.findViewById(R.id.file_transfer_layout);
fileTransferProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
fileTransferAction = (Button) view.findViewById(R.id.file_transfer_action);
messageStatus = (ImageView) view.findViewById(R.id.status);
messageSendingInProgress = (ProgressBar) view.findViewById(R.id.inprogress);
contactPictureMask = (ImageView) view.findViewById(R.id.mask);
imdmLayout = (LinearLayout) view.findViewById(R.id.imdmLayout);
imdmIcon = (ImageView) view.findViewById(R.id.imdmIcon);
imdmLabel = (TextView) view.findViewById(R.id.imdmText);
fileExtensionLabel = (TextView) view.findViewById(R.id.file_extension);
fileNameLabel = (TextView) view.findViewById(R.id.file_name);
}
@Override
public void onMsgStateChanged(ChatMessage msg, 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);
}
}
ArrayList<ChatMessage> history; ArrayList<ChatMessage> history;
Context context; Context context;
@ -1382,16 +1317,16 @@ public class ChatFragment extends Fragment implements OnClickListener, ChatMessa
public View getView(final int position, View convertView, ViewGroup parent) { public View getView(final int position, View convertView, ViewGroup parent) {
final ChatMessage message = history.get(position); final ChatMessage message = history.get(position);
View view = null; View view = null;
final ViewHolder holder; final ChatBubbleViewHolder holder;
boolean sameMessage = false; boolean sameMessage = false;
if (convertView != null) { if (convertView != null) {
view = convertView; view = convertView;
holder = (ViewHolder) view.getTag(); holder = (ChatBubbleViewHolder) view.getTag();
//LinphoneManager.removeListener(holder); //LinphoneManager.removeListener(holder);
} else { } else {
view = LayoutInflater.from(context).inflate(R.layout.chat_bubble, null); view = LayoutInflater.from(context).inflate(R.layout.chat_bubble, null);
holder = new ViewHolder(view); holder = new ChatBubbleViewHolder(view);
view.setTag(holder); view.setTag(holder);
} }

View file

@ -1,14 +1,3 @@
package org.linphone.chat;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.linphone.R;
/* /*
GroupChatFragment.java GroupChatFragment.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France Copyright (C) 2017 Belledonne Communications, Grenoble, France
@ -28,27 +17,285 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
public class GroupChatFragment extends Fragment implements View.OnClickListener { package org.linphone.chat;
private ImageView call, infos;
import android.app.Fragment;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
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.Adapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneUtils;
import org.linphone.R;
import org.linphone.activities.LinphoneActivity;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatRoom;
import org.linphone.core.ChatRoomListener;
import org.linphone.core.Content;
import org.linphone.core.Core;
import org.linphone.core.Participant;
import java.util.ArrayList;
import java.util.List;
public class GroupChatFragment extends Fragment implements ChatRoomListener {
private ImageView mBackButton, mCallButton, mBackToCallButton, mGroupInfosButton, mEditButton;
private ImageView mCancelEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton;
private ImageView mAttachImageButton, mSendMessageButton;
private TextView mRoomLabel, mRemoteComposing;
private EditText mMessageTextToSend;
private LayoutInflater mInflater; private LayoutInflater mInflater;
private Bitmap defaultContactAvatar;
private ListView mChatEventsList;
private ChatEventsAdapter mMessagesAdapter;
private String mRemoteSipUri;
private Address mRemoteSipAddress;
private ChatRoom mChatRoom;
private List<LinphoneContact> mParticipants;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain the fragment across configuration changes
setRetainInstance(true);
if (getArguments() != null && getArguments().getString("SipUri") != null) {
mRemoteSipUri = getArguments().getString("SipUri");
mRemoteSipAddress = LinphoneManager.getLc().createAddress(mRemoteSipUri);
}
defaultContactAvatar = BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.chat_picture_over);
mInflater = inflater; mInflater = inflater;
View view = inflater.inflate(R.layout.chat, container, false); View view = inflater.inflate(R.layout.chat, container, false);
call = view.findViewById(R.id.start_call); mBackButton = view.findViewById(R.id.back);
call.setVisibility(View.GONE); mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getFragmentManager().popBackStackImmediate();
}
});
infos = view.findViewById(R.id.group_infos); mCallButton = view.findViewById(R.id.start_call);
infos.setVisibility(View.VISIBLE); mCallButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LinphoneActivity.instance().setAddresGoToDialerAndCall(mRemoteSipUri, null, null);
}
});
mBackToCallButton = view.findViewById(R.id.back_to_call);
mBackToCallButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LinphoneActivity.instance().resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
}
});
mGroupInfosButton = view.findViewById(R.id.group_infos);
mGroupInfosButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mEditButton = view.findViewById(R.id.edit);
mEditButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mCancelEditButton = view.findViewById(R.id.cancel);
mCancelEditButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mSelectAllButton = view.findViewById(R.id.select_all);
mSelectAllButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mDeselectAllButton = view.findViewById(R.id.deselect_all);
mDeselectAllButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mDeleteSelectionButton = view.findViewById(R.id.delete);
mDeleteSelectionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mRoomLabel = view.findViewById(R.id.contact_name);
mAttachImageButton = view.findViewById(R.id.send_picture);
mAttachImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mSendMessageButton = view.findViewById(R.id.send_message);
mSendMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mMessageTextToSend = view.findViewById(R.id.message);
mMessageTextToSend.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mSendMessageButton.setEnabled(mMessageTextToSend.getText().length() > 0);
if (mChatRoom != null) {
mChatRoom.compose();
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
mRemoteComposing = view.findViewById(R.id.remote_composing);
mChatEventsList = view.findViewById(R.id.chat_message_list);
return view; return view;
} }
@Override @Override
public void onClick(View view) { public void onResume() {
super.onResume();
initChatRoom();
displayChatRoomHeader();
displayChatRoomHistory();
}
private void initChatRoom() {
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (mRemoteSipAddress == null || mRemoteSipUri == null || mRemoteSipUri.length() == 0 || core == null) {
LinphoneActivity.instance().goToDialerFragment();
return;
}
mChatRoom = core.getChatRoom(mRemoteSipAddress);
mChatRoom.setListener(this);
mChatRoom.markAsRead();
LinphoneActivity.instance().updateMissedChatCount();
mParticipants = new ArrayList<>();
if (mChatRoom.canHandleParticipants()) {
for (Participant p : mChatRoom.getParticipants()) {
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(p.getAddress());
if (c != null) {
mParticipants.add(c);
}
}
} else {
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(mRemoteSipAddress);
if (c != null) {
mParticipants.add(c);
}
}
}
private void displayChatRoomHeader() {
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core == null) return;
mRemoteComposing.setVisibility(View.INVISIBLE);
if (core.getCallByRemoteAddress(mRemoteSipUri) != null) {
mBackToCallButton.setVisibility(View.VISIBLE);
} else {
mBackToCallButton.setVisibility(View.GONE);
if (mChatRoom.canHandleParticipants()) {
mCallButton.setVisibility(View.GONE);
mGroupInfosButton.setVisibility(View.VISIBLE);
mRoomLabel.setText(mChatRoom.getSubject());
} else {
mCallButton.setVisibility(View.VISIBLE);
mGroupInfosButton.setVisibility(View.GONE);
if (mParticipants.size() == 0) {
// Contact not found
String displayName = mRemoteSipAddress.getDisplayName();
if (displayName == null || displayName.isEmpty()) {
mRoomLabel.setText(mRemoteSipAddress.getUsername());
} else {
mRoomLabel.setText(displayName);
}
} else {
mRoomLabel.setText(mParticipants.get(0).getFullName());
}
}
}
}
private void displayChatRoomHistory() {
mMessagesAdapter = new ChatEventsAdapter();
}
@Override
public void onUndecryptableMessageReceived(ChatRoom cr, ChatMessage msg) {
} }
@Override
public void onMessageReceived(ChatRoom cr, ChatMessage msg) {
cr.markAsRead();
LinphoneActivity.instance().updateMissedChatCount();
String externalBodyUrl = msg.getExternalBodyUrl();
Content fileTransferContent = msg.getFileTransferInformation();
if (externalBodyUrl != null || fileTransferContent != null) {
LinphoneActivity.instance().checkAndRequestExternalStoragePermission();
}
}
@Override
public void onIsComposingReceived(ChatRoom cr, Address remoteAddr, boolean isComposing) {
if (isComposing) {
mRemoteComposing.setText(getString(R.string.remote_composing_2).replace("%s", remoteAddr.getDisplayName()));
}
mRemoteComposing.setVisibility(isComposing ? View.VISIBLE : View.GONE);
}
} }

View file

@ -1,5 +1,3 @@
package org.linphone.chat;
/* /*
InfoGroupChatFragment.java InfoGroupChatFragment.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France Copyright (C) 2017 Belledonne Communications, Grenoble, France
@ -19,6 +17,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
package org.linphone.chat;
import android.app.Fragment; import android.app.Fragment;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;

View file

@ -1,5 +1,3 @@
package org.linphone.chat;
/* /*
SearchContactsListAdapter.java SearchContactsListAdapter.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France Copyright (C) 2017 Belledonne Communications, Grenoble, France
@ -19,6 +17,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
package org.linphone.chat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;