Merge branch 'feature/recyclerview'
This commit is contained in:
commit
884f4d66c6
41 changed files with 2065 additions and 1535 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -36,6 +36,7 @@ submodules/externals/build/libvpx/arm
|
|||
submodules/externals/build/libvpx/x86
|
||||
submodules/externals/build/openh264/arm
|
||||
submodules/externals/build/openh264/x86
|
||||
submodules/externals/ffmpeg/arm/
|
||||
tests/*$py.class
|
||||
tests/build.xml
|
||||
tests/project.properties
|
||||
|
|
|
@ -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"
|
||||
>
|
||||
|
||||
<activity
|
||||
android:name=".activities.LinphoneLauncherActivity"
|
||||
android:exported="true"
|
||||
|
|
|
@ -47,7 +47,10 @@ dependencies {
|
|||
if (firebaseEnable()) {
|
||||
implementation 'com.google.firebase:firebase-messaging:15.0.2'
|
||||
}
|
||||
implementation 'com.android.support:support-v4:27.0.1'
|
||||
implementation 'com.android.support:support-v4:27.1.1'
|
||||
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||
implementation 'com.android.support:design:27.1.1'
|
||||
implementation project(':liblinphone-sdk')
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class LogsActivity extends Activity {
|
|||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
// Inflate the menu; this adds items to the action context_bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.activity_logs, menu);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public class MainActivity extends Activity {
|
|||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
// Inflate the menu; this adds items to the action context_bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.activity_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public class SuitesActivity extends Activity {
|
|||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
// Inflate the menu; this adds items to the action context_bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.activity_suites, menu);
|
||||
return true;
|
||||
}
|
||||
|
|
11
res/drawable/cancel_with_padding.xml
Normal file
11
res/drawable/cancel_with_padding.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:bottom="40dp"
|
||||
android:left="20dp"
|
||||
android:right="20dp"
|
||||
android:top="40dp">
|
||||
|
||||
<bitmap android:src="@drawable/cancel_edit"/>
|
||||
</item>
|
||||
</layer-list>
|
7
res/drawable/divider.xml
Normal file
7
res/drawable/divider.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<size
|
||||
android:width="1dp"
|
||||
android:height="1dp" />
|
||||
<solid android:color="@color/colorE" />
|
||||
</shape>
|
12
res/drawable/line.xml
Normal file
12
res/drawable/line.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@android:color/darker_gray" />
|
||||
|
||||
<padding
|
||||
android:top="10dp"
|
||||
android:left="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp"/>
|
||||
</shape>
|
9
res/drawable/line_drawable.xml
Normal file
9
res/drawable/line_drawable.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!--<item-->
|
||||
<!--android:state_pressed="true"-->
|
||||
<!--android:drawable="@drawable/line"/>-->
|
||||
|
||||
<!--<item-->
|
||||
<!--android:drawable="@drawable/line"/>-->
|
||||
</selector>
|
|
@ -173,7 +173,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/footer"/>
|
||||
|
||||
<ListView
|
||||
<android.support.v7.widget.RecyclerView
|
||||
|
||||
android:id="@+id/chat_message_list"
|
||||
android:divider="@android:color/transparent"
|
||||
android:choiceMode="multipleChoice"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:clickable="false"
|
||||
android:layout_alignParentRight="true"/>
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:id="@+id/relativeLayout">
|
||||
|
||||
<ListView
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/contactsList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
|
||||
</RelativeLayout>
|
||||
|
||||
<ListView
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/chat_room_participants"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -107,7 +107,7 @@
|
|||
android:divider="@color/colorE"
|
||||
android:dividerHeight="1dp">
|
||||
|
||||
</ListView>
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/leaveGroupLayout"
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
<include layout="@layout/edit_list"/>
|
||||
|
||||
<ListView
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/chatList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -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">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/delete_chatroom"
|
||||
|
@ -14,6 +15,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"
|
||||
|
@ -121,5 +123,11 @@
|
|||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:id="@+id/selected_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/notification_color_led"
|
||||
android:visibility="invisible" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -69,6 +69,7 @@
|
|||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:visibility="gone"
|
||||
android:clickable="false"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingRight="5dp" />
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@color/colorH"
|
||||
android:orientation="vertical" >
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/top_bar"
|
||||
|
@ -119,13 +120,18 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
<!--android:fastScrollAlwaysVisible="true"-->
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/contactsList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="@color/colorE"
|
||||
android:fastScrollEnabled="true"
|
||||
android:fastScrollAlwaysVisible="true"
|
||||
app:fastScrollEnabled="true"
|
||||
app:fastScrollHorizontalThumbDrawable="@drawable/fast_scroll"
|
||||
app:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
|
||||
app:fastScrollVerticalThumbDrawable="@drawable/fast_scroll"
|
||||
app:fastScrollVerticalTrackDrawable="@drawable/line_drawable"
|
||||
|
||||
android:dividerHeight="1dp" />
|
||||
|
||||
<ProgressBar
|
||||
|
|
135
res/layout/context_bar.xml
Normal file
135
res/layout/context_bar.xml
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/context_bar"
|
||||
android:background="@color/colorA"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!--<RelativeLayout-->
|
||||
<!--android:id="@+id/status_bar"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="40dp"-->
|
||||
<!--android:layout_alignParentTop="true">-->
|
||||
|
||||
<!--<ImageView-->
|
||||
<!--android:id="@+id/side_menu_button"-->
|
||||
<!--android:src="@drawable/menu_burger"-->
|
||||
<!--android:contentDescription="@string/content_description_menu"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:padding="10dp"-->
|
||||
<!--android:layout_centerInParent="true"-->
|
||||
<!--android:layout_alignParentLeft="true"/>-->
|
||||
|
||||
<!--<ImageView-->
|
||||
<!--android:id="@+id/call_quality"-->
|
||||
<!--android:src="@drawable/call_quality_indicator_0"-->
|
||||
<!--android:contentDescription="@string/content_description_call_quality"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:padding="10dp"-->
|
||||
<!--android:layout_centerInParent="true"-->
|
||||
<!--android:layout_alignParentLeft="true"-->
|
||||
<!--android:visibility="invisible" />-->
|
||||
|
||||
<!--<ImageView-->
|
||||
<!--android:id="@+id/status_led"-->
|
||||
<!--android:src="@drawable/led_disconnected"-->
|
||||
<!--android:paddingLeft="5dp"-->
|
||||
<!--android:adjustViewBounds="true"-->
|
||||
<!--android:layout_width="20dp"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_centerInParent="true"-->
|
||||
<!--android:layout_toRightOf="@id/side_menu_button"/>-->
|
||||
|
||||
<!--<TextView-->
|
||||
<!--android:id="@+id/status_text"-->
|
||||
<!--android:text="@string/status_not_connected"-->
|
||||
<!--style="@style/font16"-->
|
||||
<!--android:paddingLeft="5dp"-->
|
||||
<!--android:layout_centerVertical="true"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:gravity="center_vertical"-->
|
||||
<!--android:layout_toRightOf="@id/status_led" />-->
|
||||
|
||||
<!--<ImageView-->
|
||||
<!--android:id="@+id/voicemail"-->
|
||||
<!--android:src="@drawable/voicemail"-->
|
||||
<!--android:layout_centerVertical="true"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:gravity="center_vertical"-->
|
||||
<!--android:visibility="gone" />-->
|
||||
|
||||
<!--<TextView-->
|
||||
<!--android:id="@+id/voicemail_count"-->
|
||||
<!--style="@style/font16"-->
|
||||
<!--android:layout_alignParentRight="true"-->
|
||||
<!--android:paddingLeft="5dp"-->
|
||||
<!--android:paddingRight="10dp"-->
|
||||
<!--android:layout_centerVertical="true"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:visibility="gone" />-->
|
||||
|
||||
<!--<ImageView-->
|
||||
<!--android:id="@+id/encryption"-->
|
||||
<!--android:src="@drawable/security_ko"-->
|
||||
<!--android:contentDescription="@string/content_description_encryption"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:adjustViewBounds="true"-->
|
||||
<!--android:padding="5dp"-->
|
||||
<!--android:layout_centerInParent="true"-->
|
||||
<!--android:visibility="gone"-->
|
||||
<!--android:layout_alignParentRight="true" />-->
|
||||
<!--</RelativeLayout>-->
|
||||
<LinearLayout
|
||||
android:id="@+id/top_bar"
|
||||
android:orientation="horizontal"
|
||||
android:background="@color/colorF"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/new_discussion"
|
||||
android:src="@drawable/chat_add"
|
||||
android:background="@drawable/toolbar_button"
|
||||
android:contentDescription="@string/content_description_new_discussion"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.2"
|
||||
android:padding="15dp"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back_in_call"
|
||||
android:src="@drawable/call_back"
|
||||
android:background="@drawable/toolbar_button"
|
||||
android:contentDescription="@string/content_description_back_call"
|
||||
android:visibility="invisible"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.2"
|
||||
android:padding="15dp"/>
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.4"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/edit"
|
||||
android:src="@drawable/edit_list_button"
|
||||
android:background="@drawable/toolbar_button"
|
||||
android:contentDescription="@string/content_description_edit_list"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.2"
|
||||
android:padding="15dp"/>
|
||||
<include layout="@layout/edit_list"/>
|
||||
</LinearLayout>
|
||||
</android.support.v7.widget.Toolbar>
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<include layout="@layout/edit_list"/>
|
||||
|
||||
<ListView
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/history_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/history_whole"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
|
@ -53,6 +54,7 @@
|
|||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:visibility="gone"
|
||||
android:clickable="false"
|
||||
android:padding="5dp" />
|
||||
|
||||
<RelativeLayout
|
||||
|
|
|
@ -6,12 +6,16 @@
|
|||
<item name="android:fastScrollTextColor">@android:color/white</item>
|
||||
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</item>
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
<style name="NoTitle" parent="android:Theme.Holo.Light.NoActionBar">
|
||||
<item name="android:fastScrollThumbDrawable">@drawable/fast_scroll</item>
|
||||
<item name="android:fastScrollTextColor">@android:color/white</item>
|
||||
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</item>
|
||||
|
||||
</style>
|
||||
<style name="FullScreen" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen">
|
||||
<style name="FullScreen" parent="android:Theme.Holo.Light.NoActionBar">
|
||||
<item name="android:fastScrollThumbDrawable">@drawable/fast_scroll</item>
|
||||
<item name="android:fastScrollTextColor">@android:color/white</item>
|
||||
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</item>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../libs
|
|
@ -1630,6 +1630,7 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
|||
menu.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
if(sideMenu.isDrawerVisible(Gravity.LEFT)){
|
||||
sideMenu.closeDrawer(sideMenuContent);
|
||||
} else {
|
||||
|
|
|
@ -152,8 +152,8 @@ public class CodecDownloaderFragment extends Fragment {
|
|||
if (savedInstanceState.containsKey("downloaded"))
|
||||
downloaded.setVisibility((Integer) savedInstanceState.getSerializable("downloaded"));
|
||||
|
||||
if (savedInstanceState.containsKey("bar"))
|
||||
bar.setVisibility((Integer) savedInstanceState.getSerializable("bar"));
|
||||
if (savedInstanceState.containsKey("context_bar"))
|
||||
bar.setVisibility((Integer) savedInstanceState.getSerializable("context_bar"));
|
||||
|
||||
if (savedInstanceState.containsKey("downloadingInfo"))
|
||||
downloadingInfo.setVisibility((Integer) savedInstanceState.getSerializable("downloadingInfo"));
|
||||
|
@ -177,7 +177,7 @@ public class CodecDownloaderFragment extends Fragment {
|
|||
if (yes != null) outState.putSerializable("yes", yes.getVisibility());
|
||||
if (no != null) outState.putSerializable("no", no.getVisibility());
|
||||
if (ok != null) outState.putSerializable("ok", ok.getVisibility());
|
||||
if (bar != null) outState.putSerializable("bar", bar.getVisibility());
|
||||
if (bar != null) outState.putSerializable("context_bar", bar.getVisibility());
|
||||
if (downloadingInfo != null) outState.putSerializable("downloadingInfo", downloadingInfo.getVisibility());
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
|
238
src/android/org/linphone/call/CallHistoryAdapter.java
Normal file
238
src/android/org/linphone/call/CallHistoryAdapter.java
Normal file
|
@ -0,0 +1,238 @@
|
|||
package org.linphone.call;
|
||||
|
||||
/*
|
||||
CallHistoryAdapter.java
|
||||
Copyright (C) 2018 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.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
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.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
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.Call;
|
||||
import org.linphone.core.CallLog;
|
||||
import org.linphone.ui.SelectableAdapter;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
public class CallHistoryAdapter extends SelectableAdapter<CallHistoryAdapter.ViewHolder> {
|
||||
|
||||
//This ViewHolder links fields from the xml to variables that will display values provided by the adapter
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
|
||||
View.OnLongClickListener{
|
||||
public TextView contact;
|
||||
public ImageView detail;
|
||||
public CheckBox select;
|
||||
public ImageView callDirection;
|
||||
public ImageView contactPicture;
|
||||
public RelativeLayout CallContact;
|
||||
public LinearLayout separator;
|
||||
public TextView separatorText;
|
||||
private CallHistoryAdapter.ViewHolder.ClickListener listener;
|
||||
|
||||
public ViewHolder(View view, CallHistoryAdapter.ViewHolder.ClickListener listener) {
|
||||
super(view);
|
||||
contact = (TextView) view.findViewById(R.id.sip_uri);
|
||||
detail = (ImageView) view.findViewById(R.id.detail);
|
||||
select = (CheckBox) view.findViewById(R.id.delete);
|
||||
callDirection = (ImageView) view.findViewById(R.id.icon);
|
||||
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
|
||||
CallContact = (RelativeLayout) view.findViewById(R.id.history_click);
|
||||
separator = (LinearLayout) view.findViewById(R.id.separator);
|
||||
separatorText = (TextView) view.findViewById(R.id.separator_text);
|
||||
this.listener = listener;
|
||||
view.setOnClickListener(this);
|
||||
view.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (listener != null) {
|
||||
listener.onItemClicked(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
if (listener != null) {
|
||||
return listener.onItemLongClicked(getAdapterPosition());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface ClickListener {
|
||||
void onItemClicked(int position);
|
||||
boolean onItemLongClicked(int position);
|
||||
}
|
||||
}
|
||||
|
||||
private List<CallLog> mLogs;
|
||||
private Context mContext;
|
||||
private CallHistoryAdapter.ViewHolder.ClickListener clickListener;
|
||||
|
||||
public CallHistoryAdapter(Context aContext, List<CallLog> logs,CallHistoryAdapter.ViewHolder.ClickListener listener ,SelectableHelper helper) {
|
||||
super(helper);
|
||||
this.mLogs = logs;
|
||||
this.mContext = aContext;
|
||||
this.clickListener = listener;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mLogs.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return mLogs.get(position);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_cell, parent, false);
|
||||
return new ViewHolder(v, clickListener);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
|
||||
final CallLog log= mLogs.get(position);
|
||||
long timestamp = log.getStartDate() * 1000;
|
||||
Address address;
|
||||
|
||||
holder.contact.setSelected(true); // For automated horizontal scrolling of long texts
|
||||
Calendar logTime = Calendar.getInstance();
|
||||
logTime.setTimeInMillis(timestamp);
|
||||
holder.separatorText.setText(timestampToHumanDate(logTime));
|
||||
holder.select.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE);
|
||||
holder.select.setChecked(isSelected(position));
|
||||
|
||||
if (position > 0) {
|
||||
CallLog previousLog = mLogs.get(position-1);
|
||||
long previousTimestamp = previousLog.getStartDate() * 1000;
|
||||
Calendar previousLogTime = Calendar.getInstance();
|
||||
previousLogTime.setTimeInMillis(previousTimestamp);
|
||||
|
||||
if (isSameDay(previousLogTime, logTime)) {
|
||||
holder.separator.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.separator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
holder.separator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (log.getDir() == Call.Dir.Incoming) {
|
||||
address = log.getFromAddress();
|
||||
if (log.getStatus() == Call.Status.Missed) {
|
||||
holder.callDirection.setImageResource(R.drawable.call_status_missed);
|
||||
} else {
|
||||
holder.callDirection.setImageResource(R.drawable.call_status_incoming);
|
||||
}
|
||||
} else {
|
||||
address = log.getToAddress();
|
||||
holder.callDirection.setImageResource(R.drawable.call_status_outgoing);
|
||||
}
|
||||
|
||||
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
|
||||
String displayName = null;
|
||||
final String sipUri = (address != null) ? address.asString() : "";
|
||||
if (c != null) {
|
||||
displayName = c.getFullName();
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, c.getThumbnailUri());
|
||||
} else {
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
}
|
||||
|
||||
if (displayName == null) {
|
||||
holder.contact.setText(LinphoneUtils.getAddressDisplayName(sipUri));
|
||||
} else {
|
||||
holder.contact.setText(displayName);
|
||||
}
|
||||
|
||||
holder.detail.setVisibility(isEditionEnabled() ? View.INVISIBLE : View.VISIBLE);
|
||||
holder.detail.setOnClickListener(!isEditionEnabled() ?
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().displayHistoryDetail(sipUri, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
:
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mLogs.size();
|
||||
}
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
private String timestampToHumanDate(Calendar cal) {
|
||||
SimpleDateFormat dateFormat;
|
||||
if (isToday(cal)) {
|
||||
return mContext.getString(R.string.today);
|
||||
} else if (isYesterday(cal)) {
|
||||
return mContext.getString(R.string.yesterday);
|
||||
} else {
|
||||
dateFormat = new SimpleDateFormat(mContext.getResources().getString(R.string.history_date_format));
|
||||
}
|
||||
|
||||
return dateFormat.format(cal.getTime());
|
||||
}
|
||||
|
||||
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 boolean isToday(Calendar cal) {
|
||||
return isSameDay(cal, Calendar.getInstance());
|
||||
}
|
||||
|
||||
private boolean isYesterday(Calendar cal) {
|
||||
Calendar yesterday = Calendar.getInstance();
|
||||
yesterday.roll(Calendar.DAY_OF_MONTH, -1);
|
||||
return isSameDay(cal, yesterday);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
package org.linphone.chat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
|
@ -29,12 +31,13 @@ import android.widget.RelativeLayout;
|
|||
import android.widget.TextView;
|
||||
|
||||
import org.linphone.R;
|
||||
import org.linphone.core.ChatMessage;
|
||||
|
||||
public class ChatBubbleViewHolder {
|
||||
public class ChatBubbleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
|
||||
public String messageId;
|
||||
|
||||
public Context mContext;
|
||||
public ChatMessage message;
|
||||
public LinearLayout eventLayout;
|
||||
//public TextView eventTime;
|
||||
public TextView eventMessage;
|
||||
|
||||
public RelativeLayout bubbleLayout;
|
||||
|
@ -61,35 +64,84 @@ public class ChatBubbleViewHolder {
|
|||
public Button openFileButton;
|
||||
|
||||
public CheckBox delete;
|
||||
private ClickListener listener;
|
||||
|
||||
public ChatBubbleViewHolder(View view) {
|
||||
eventLayout = view.findViewById(R.id.event);
|
||||
public ChatBubbleViewHolder(Context context, View view, ClickListener listener) {
|
||||
super(view);
|
||||
this.mContext = context;
|
||||
|
||||
this.eventLayout = view.findViewById(R.id.event);
|
||||
//eventTime = view.findViewById(R.id.event_date);
|
||||
eventMessage = view.findViewById(R.id.event_text);
|
||||
this.eventMessage = view.findViewById(R.id.event_text);
|
||||
|
||||
bubbleLayout = view.findViewById(R.id.bubble);
|
||||
separatorLayout = view.findViewById(R.id.separator);
|
||||
background = view.findViewById(R.id.background);
|
||||
contactPicture = view.findViewById(R.id.contact_picture);
|
||||
contactPictureMask = view.findViewById(R.id.mask);
|
||||
contactName = view.findViewById(R.id.contact_header);
|
||||
this.bubbleLayout = view.findViewById(R.id.bubble);
|
||||
this.background = view.findViewById(R.id.background);
|
||||
this.contactPicture = view.findViewById(R.id.contact_picture);
|
||||
this.contactPictureMask = view.findViewById(R.id.mask);
|
||||
this.contactName = view.findViewById(R.id.contact_header);
|
||||
|
||||
messageStatus = view.findViewById(R.id.status);
|
||||
messageSendingInProgress = view.findViewById(R.id.inprogress);
|
||||
imdmLayout = view.findViewById(R.id.imdmLayout);
|
||||
imdmIcon = view.findViewById(R.id.imdmIcon);
|
||||
imdmLabel = view.findViewById(R.id.imdmText);
|
||||
this.messageStatus = view.findViewById(R.id.status);
|
||||
this.messageSendingInProgress = view.findViewById(R.id.inprogress);
|
||||
this.imdmLayout = view.findViewById(R.id.imdmLayout);
|
||||
this.imdmIcon = view.findViewById(R.id.imdmIcon);
|
||||
this.imdmLabel = view.findViewById(R.id.imdmText);
|
||||
|
||||
messageText = view.findViewById(R.id.message);
|
||||
messageImage = view.findViewById(R.id.image);
|
||||
this.messageText = view.findViewById(R.id.message);
|
||||
this.messageImage = view.findViewById(R.id.image);
|
||||
this.separatorLayout = view.findViewById(R.id.separator);
|
||||
|
||||
fileTransferLayout = view.findViewById(R.id.file_transfer_layout);
|
||||
fileTransferProgressBar = view.findViewById(R.id.progress_bar);
|
||||
fileTransferAction = view.findViewById(R.id.file_transfer_action);
|
||||
this.fileTransferLayout = view.findViewById(R.id.file_transfer_layout);
|
||||
this.fileTransferProgressBar = view.findViewById(R.id.progress_bar);
|
||||
this.fileTransferAction = view.findViewById(R.id.file_transfer_action);
|
||||
|
||||
fileName = view.findViewById(R.id.file_name);
|
||||
openFileButton = view.findViewById(R.id.open_file);
|
||||
this.fileName = view.findViewById(R.id.file_name);
|
||||
this.openFileButton = view.findViewById(R.id.open_file);
|
||||
|
||||
delete = view.findViewById(R.id.delete_message);
|
||||
this.delete = view.findViewById(R.id.delete_message);
|
||||
|
||||
this.listener = listener;
|
||||
|
||||
view.setOnClickListener(this);
|
||||
}
|
||||
public ChatBubbleViewHolder(View view) {
|
||||
super(view);
|
||||
this.eventLayout = view.findViewById(R.id.event);
|
||||
//eventTime = view.findViewById(R.id.event_date);
|
||||
this.eventMessage = view.findViewById(R.id.event_text);
|
||||
|
||||
this.bubbleLayout = view.findViewById(R.id.bubble);
|
||||
this.background = view.findViewById(R.id.background);
|
||||
this.contactPicture = view.findViewById(R.id.contact_picture);
|
||||
this.contactPictureMask = view.findViewById(R.id.mask);
|
||||
this.contactName = view.findViewById(R.id.contact_header);
|
||||
|
||||
this.messageStatus = view.findViewById(R.id.status);
|
||||
this.messageSendingInProgress = view.findViewById(R.id.inprogress);
|
||||
this.imdmLayout = view.findViewById(R.id.imdmLayout);
|
||||
this.imdmIcon = view.findViewById(R.id.imdmIcon);
|
||||
this.imdmLabel = view.findViewById(R.id.imdmText);
|
||||
|
||||
this.messageText = view.findViewById(R.id.message);
|
||||
this.messageImage = view.findViewById(R.id.image);
|
||||
this.separatorLayout = view.findViewById(R.id.separator);
|
||||
|
||||
this.fileTransferLayout = view.findViewById(R.id.file_transfer_layout);
|
||||
this.fileTransferProgressBar = view.findViewById(R.id.progress_bar);
|
||||
this.fileTransferAction = view.findViewById(R.id.file_transfer_action);
|
||||
|
||||
this.fileName = view.findViewById(R.id.file_name);
|
||||
this.openFileButton = view.findViewById(R.id.open_file);
|
||||
|
||||
this.delete = view.findViewById(R.id.delete_message);
|
||||
}
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(listener!=null) {
|
||||
listener.onItemClicked(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public interface ClickListener {
|
||||
void onItemClicked(int position);
|
||||
}
|
||||
}
|
|
@ -21,48 +21,46 @@ package org.linphone.chat;
|
|||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.linphone.LinphoneManager;
|
||||
import org.linphone.LinphonePreferences;
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.contacts.ContactAddress;
|
||||
import org.linphone.contacts.ContactsManager;
|
||||
import org.linphone.contacts.LinphoneNumberOrAddress;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.contacts.SearchContactsListAdapter;
|
||||
import org.linphone.core.Address;
|
||||
import org.linphone.core.ChatRoom;
|
||||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.Factory;
|
||||
import org.linphone.core.ProxyConfig;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.ui.ContactSelectView;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||
|
||||
public class ChatCreationFragment extends Fragment implements View.OnClickListener, AdapterView.OnItemClickListener, ContactsUpdatedListener {
|
||||
private LayoutInflater mInflater;
|
||||
private ListView mContactsList;
|
||||
public class ChatCreationFragment extends Fragment implements View.OnClickListener ,SearchContactsListAdapter.ViewHolder.ClickListener, ContactsUpdatedListener {
|
||||
private RecyclerView mContactsList;
|
||||
private LinearLayout mContactsSelectedLayout;
|
||||
private HorizontalScrollView mContactsSelectLayout;
|
||||
private ArrayList<ContactAddress> mContactsSelected;
|
||||
|
@ -80,7 +78,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
|||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
mInflater = inflater;
|
||||
super.onCreate(savedInstanceState);
|
||||
View view = inflater.inflate(R.layout.chat_create, container, false);
|
||||
|
||||
mContactsSelected = new ArrayList<>();
|
||||
|
@ -124,7 +122,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
|||
mContactsFetchInProgress = view.findViewById(R.id.contactsFetchInProgress);
|
||||
mContactsFetchInProgress.setVisibility(View.VISIBLE);
|
||||
|
||||
mSearchAdapter = new SearchContactsListAdapter(null, mInflater, mContactsFetchInProgress);
|
||||
mSearchAdapter = new SearchContactsListAdapter(null, mContactsFetchInProgress, this);
|
||||
|
||||
mSearchField = view.findViewById(R.id.searchField);
|
||||
mSearchField.addTextChangedListener(new TextWatcher() {
|
||||
|
@ -146,8 +144,23 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
|||
}
|
||||
});
|
||||
|
||||
//Declares the layout manager, allowing customization of RecyclerView displaying
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
|
||||
|
||||
|
||||
|
||||
mContactsList.setAdapter(mSearchAdapter);
|
||||
mContactsList.setOnItemClickListener(this);
|
||||
|
||||
//Divider between items + binds layout manager to our RecyclerView
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mContactsList.getContext(),
|
||||
layoutManager.getOrientation());
|
||||
dividerItemDecoration.setDrawable(getActivity().getApplicationContext().getResources().getDrawable(R.drawable.divider));
|
||||
mContactsList.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
mContactsList.setLayoutManager(layoutManager);
|
||||
|
||||
|
||||
|
||||
if (savedInstanceState != null && savedInstanceState.getStringArrayList("mContactsSelected") != null) {
|
||||
mContactsSelectedLayout.removeAllViews();
|
||||
// We need to get all contacts not only sip
|
||||
|
@ -329,7 +342,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
|||
|
||||
private void removeContactFromSelection(ContactAddress ca) {
|
||||
updateContactsClick(ca, mSearchAdapter.getContactsSelectedList());
|
||||
mSearchAdapter.notifyDataSetInvalidated();
|
||||
mSearchAdapter.notifyDataSetChanged();
|
||||
updateListSelected();
|
||||
}
|
||||
|
||||
|
@ -348,6 +361,8 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
|||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
|
||||
//Removed all selection mode related code, as it is now located into SelectableHelper.
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
int id = view.getId();
|
||||
|
@ -412,8 +427,8 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
ContactAddress ca = mSearchAdapter.getContacts().get(i);
|
||||
public void onItemClicked(int position) {
|
||||
ContactAddress ca = mSearchAdapter.getContacts().get(position);
|
||||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
ProxyConfig lpc = lc.getDefaultProxyConfig();
|
||||
if (lpc == null || lpc.getConferenceFactoryUri() == null) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import android.net.Uri;
|
|||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.text.Spanned;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
|
@ -56,12 +57,11 @@ import org.linphone.core.Address;
|
|||
import org.linphone.core.ChatMessage;
|
||||
import org.linphone.core.ChatMessageListenerStub;
|
||||
import org.linphone.core.Content;
|
||||
import org.linphone.core.Event;
|
||||
import org.linphone.core.EventLog;
|
||||
import org.linphone.core.LimeState;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.ui.ListSelectionAdapter;
|
||||
import org.linphone.ui.ListSelectionHelper;
|
||||
import org.linphone.ui.SelectableAdapter;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -73,26 +73,29 @@ import java.util.List;
|
|||
|
||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||
|
||||
public class ChatEventsAdapter extends ListSelectionAdapter {
|
||||
|
||||
public class ChatEventsAdapter extends SelectableAdapter<ChatBubbleViewHolder> {
|
||||
|
||||
private static int MARGIN_BETWEEN_MESSAGES = 10;
|
||||
private static int SIDE_MARGIN = 100;
|
||||
|
||||
private Context mContext;
|
||||
private List<EventLog> mHistory;
|
||||
private List<LinphoneContact> mParticipants;
|
||||
private LayoutInflater mLayoutInflater;
|
||||
private int mItemResource;
|
||||
private Bitmap mDefaultBitmap;
|
||||
private GroupChatFragment mFragment;
|
||||
private ChatMessageListenerStub mListener;
|
||||
|
||||
public ChatEventsAdapter(GroupChatFragment fragment, ListSelectionHelper helper, LayoutInflater inflater, EventLog[] history, ArrayList<LinphoneContact> participants) {
|
||||
super(helper);
|
||||
mFragment = fragment;
|
||||
mContext = mFragment.getActivity();
|
||||
mLayoutInflater = inflater;
|
||||
mHistory = new ArrayList<>(Arrays.asList(history));
|
||||
mParticipants = participants;
|
||||
private ChatBubbleViewHolder.ClickListener mClickListener;
|
||||
|
||||
public ChatEventsAdapter(GroupChatFragment fragment, SelectableHelper helper, int itemResource, EventLog[] history, ArrayList<LinphoneContact> participants, ChatBubbleViewHolder.ClickListener clickListener) {
|
||||
super(helper);
|
||||
mFragment = fragment;
|
||||
mContext = mFragment.getActivity();
|
||||
mItemResource = itemResource;
|
||||
mHistory = new ArrayList<>(Arrays.asList(history));
|
||||
mParticipants = participants;
|
||||
mClickListener = clickListener;
|
||||
mListener = new ChatMessageListenerStub() {
|
||||
@Override
|
||||
public void onFileTransferProgressIndication(ChatMessage message, Content content, int offset, int total) {
|
||||
|
@ -124,6 +127,284 @@ public class ChatEventsAdapter extends ListSelectionAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatBubbleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext())
|
||||
.inflate(this.mItemResource, parent, false);
|
||||
ChatBubbleViewHolder VH = new ChatBubbleViewHolder(this.mContext,v, mClickListener);
|
||||
|
||||
//Allows onLongClick ContextMenu on bubbles
|
||||
mFragment.registerForContextMenu(v);
|
||||
v.setTag(VH);
|
||||
return VH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ChatBubbleViewHolder holder, int position) {
|
||||
final EventLog event = this.mHistory.get(position);
|
||||
holder.eventLayout.setVisibility(View.GONE);
|
||||
holder.bubbleLayout.setVisibility(View.GONE);
|
||||
holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE);
|
||||
holder.messageText.setVisibility(View.GONE);
|
||||
holder.messageImage.setVisibility(View.GONE);
|
||||
holder.fileTransferLayout.setVisibility(View.GONE);
|
||||
holder.fileTransferProgressBar.setProgress(0);
|
||||
holder.fileTransferAction.setEnabled(true);
|
||||
holder.fileName.setVisibility(View.GONE);
|
||||
holder.openFileButton.setVisibility(View.GONE);
|
||||
holder.messageStatus.setVisibility(View.INVISIBLE);
|
||||
holder.messageSendingInProgress.setVisibility(View.GONE);
|
||||
holder.imdmLayout.setVisibility(View.INVISIBLE);
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
|
||||
if (isEditionEnabled()) {
|
||||
holder.delete.setOnCheckedChangeListener(null);
|
||||
holder.delete.setChecked(isSelected(position));
|
||||
holder.delete.setTag(position);
|
||||
}
|
||||
|
||||
if (event.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||
holder.bubbleLayout.setVisibility(View.VISIBLE);
|
||||
final ChatMessage message = event.getChatMessage();
|
||||
|
||||
if (position > 0 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
|
||||
EventLog previousEvent = (EventLog)getItem(position-1);
|
||||
if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||
ChatMessage previousMessage = previousEvent.getChatMessage();
|
||||
if (previousMessage.getFromAddress().weakEqual(message.getFromAddress())) {
|
||||
holder.separatorLayout.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
// No separator if previous event is not a message
|
||||
holder.separatorLayout.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
holder.messageId = message.getMessageId();
|
||||
message.setUserData(holder);
|
||||
|
||||
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;
|
||||
|
||||
LinphoneContact contact = null;
|
||||
if (message.isOutgoing()) {
|
||||
message.setListener(mListener);
|
||||
|
||||
if (status == ChatMessage.State.InProgress) {
|
||||
holder.messageSendingInProgress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!message.isSecured() && LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory && status != ChatMessage.State.InProgress) {
|
||||
holder.messageStatus.setVisibility(View.VISIBLE);
|
||||
holder.messageStatus.setImageResource(R.drawable.chat_unsecure);
|
||||
}
|
||||
|
||||
if (status == ChatMessage.State.Delivered) {
|
||||
/*holder.imdmLayout.setVisibility(View.VISIBLE);
|
||||
holder.imdmLabel.setText(R.string.sent);
|
||||
holder.imdmIcon.setImageResource(R.drawable.chat_delivered);
|
||||
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorD));*/
|
||||
} else 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.error);
|
||||
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI));
|
||||
} else if (status == ChatMessage.State.FileTransferError) {
|
||||
holder.imdmLayout.setVisibility(View.VISIBLE);
|
||||
holder.imdmIcon.setImageResource(R.drawable.chat_error);
|
||||
holder.imdmLabel.setText(R.string.file_transfer_error);
|
||||
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI));
|
||||
}
|
||||
|
||||
//layoutParams allow bubbles alignment during selection mode
|
||||
if (isEditionEnabled()) {
|
||||
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
|
||||
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
||||
} else {
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
||||
}
|
||||
|
||||
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 {
|
||||
for (LinphoneContact c : mParticipants) {
|
||||
if (c != null && c.hasAddress(remoteSender.asStringUriOnly())) {
|
||||
contact = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEditionEnabled()) {
|
||||
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
|
||||
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
||||
} else {
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
layoutParams.setMargins(0, MARGIN_BETWEEN_MESSAGES/2, SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (contact == null) {
|
||||
contact = ContactsManager.getInstance().findContactFromAddress(remoteSender);
|
||||
}
|
||||
if (contact != null) {
|
||||
if (contact.getFullName() != null) {
|
||||
displayName = contact.getFullName();
|
||||
} else {
|
||||
displayName = LinphoneUtils.getAddressDisplayName(remoteSender);
|
||||
}
|
||||
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
if (contact.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri());
|
||||
}
|
||||
} else {
|
||||
displayName = LinphoneUtils.getAddressDisplayName(remoteSender);
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
}
|
||||
holder.contactName.setText(LinphoneUtils.timestampToHumanDate(mContext, message.getTime(), R.string.messages_date_format) + " - " + displayName);
|
||||
|
||||
if (message.hasTextContent()) {
|
||||
String msg = message.getTextContent();
|
||||
Spanned text = LinphoneUtils.getTextWithHttpLinks(msg);
|
||||
holder.messageText.setText(text);
|
||||
holder.messageText.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
holder.messageText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
String externalBodyUrl = message.getExternalBodyUrl();
|
||||
Content fileTransferContent = message.getFileTransferInformation();
|
||||
|
||||
if (message.getAppdata() != null) { // Something to display
|
||||
displayAttachedFile(message, holder);
|
||||
}
|
||||
|
||||
if (externalBodyUrl != null) { // Incoming file transfer not yet downloaded
|
||||
holder.fileName.setVisibility(View.VISIBLE);
|
||||
holder.fileName.setText(fileTransferContent.getName());
|
||||
|
||||
holder.fileTransferLayout.setVisibility(View.VISIBLE);
|
||||
holder.fileTransferProgressBar.setVisibility(View.GONE);
|
||||
if (message.isFileTransferInProgress()) { // Incoming file transfer in progress
|
||||
holder.fileTransferAction.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.fileTransferAction.setText(mContext.getString(R.string.accept));
|
||||
holder.fileTransferAction.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mContext.getPackageManager().checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
|
||||
v.setEnabled(false);
|
||||
String filename = message.getFileTransferInformation().getName();
|
||||
File file = new File(Environment.getExternalStorageDirectory(), filename);
|
||||
int prefix = 1;
|
||||
while (file.exists()) {
|
||||
file = new File(Environment.getExternalStorageDirectory(), prefix + "_" + filename);
|
||||
Log.w("File with that name already exists, renamed to " + prefix + "_" + filename);
|
||||
prefix += 1;
|
||||
}
|
||||
message.setListener(mListener);
|
||||
message.setFileTransferFilepath(file.getPath());
|
||||
message.downloadFile();
|
||||
|
||||
} else {
|
||||
Log.w("WRITE_EXTERNAL_STORAGE permission not granted, won't be able to store the downloaded file");
|
||||
LinphoneActivity.instance().checkAndRequestExternalStoragePermission();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (message.isFileTransferInProgress()) { // Outgoing file transfer in progress
|
||||
message.setListener(mListener); // add the listener for file upload progress display
|
||||
holder.messageSendingInProgress.setVisibility(View.GONE);
|
||||
holder.fileTransferLayout.setVisibility(View.VISIBLE);
|
||||
holder.fileTransferAction.setText(mContext.getString(R.string.cancel));
|
||||
holder.fileTransferAction.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
message.cancelFileTransfer();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
holder.bubbleLayout.setLayoutParams(layoutParams);
|
||||
} else { // Event is not chat message
|
||||
holder.eventLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
Address address = event.getParticipantAddress();
|
||||
String displayName = null;
|
||||
if (address != null) {
|
||||
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
|
||||
if (contact != null) {
|
||||
displayName = contact.getFullName();
|
||||
} else {
|
||||
displayName = LinphoneUtils.getAddressDisplayName(address);
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.getType()) {
|
||||
case ConferenceCreated:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.conference_created));
|
||||
break;
|
||||
case ConferenceTerminated:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.conference_destroyed));
|
||||
break;
|
||||
case ConferenceParticipantAdded:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.participant_added).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantRemoved:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.participant_removed).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceSubjectChanged:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.subject_changed).replace("%s", event.getSubject()));
|
||||
break;
|
||||
case ConferenceParticipantSetAdmin:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.admin_set).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantUnsetAdmin:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.admin_unset).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantDeviceAdded:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.device_added).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantDeviceRemoved:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.device_removed).replace("%s", displayName));
|
||||
break;
|
||||
case None:
|
||||
default:
|
||||
//TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return this.mHistory.size();
|
||||
}
|
||||
|
||||
public void addToHistory(EventLog log) {
|
||||
mHistory.add(log);
|
||||
notifyDataSetChanged();
|
||||
|
@ -148,299 +429,19 @@ public class ChatEventsAdapter extends ListSelectionAdapter {
|
|||
mHistory.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mHistory.size();
|
||||
return this.mHistory.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int i) {
|
||||
return mHistory.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
public void removeItem(int i) {
|
||||
public void removeItem(int i) {
|
||||
mHistory.remove(i);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
||||
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);
|
||||
}
|
||||
|
||||
holder.eventLayout.setVisibility(View.GONE);
|
||||
holder.bubbleLayout.setVisibility(View.GONE);
|
||||
holder.separatorLayout.setVisibility(i == 0 ? View.GONE : View.VISIBLE); // Hide separator if first item in list
|
||||
holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE);
|
||||
holder.messageText.setVisibility(View.GONE);
|
||||
holder.messageImage.setVisibility(View.GONE);
|
||||
holder.fileTransferLayout.setVisibility(View.GONE);
|
||||
holder.fileTransferProgressBar.setProgress(0);
|
||||
holder.fileTransferAction.setEnabled(true);
|
||||
holder.fileName.setVisibility(View.GONE);
|
||||
holder.openFileButton.setVisibility(View.GONE);
|
||||
holder.messageStatus.setVisibility(View.INVISIBLE);
|
||||
holder.messageSendingInProgress.setVisibility(View.GONE);
|
||||
holder.imdmLayout.setVisibility(View.INVISIBLE);
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
|
||||
if (isEditionEnabled()) {
|
||||
holder.delete.setOnCheckedChangeListener(null);
|
||||
holder.delete.setChecked(getSelectedItemsPosition().contains(i));
|
||||
holder.delete.setTag(i);
|
||||
holder.delete.setOnCheckedChangeListener(getDeleteListener());
|
||||
}
|
||||
|
||||
EventLog event = (EventLog)getItem(i);
|
||||
if (event.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||
holder.bubbleLayout.setVisibility(View.VISIBLE);
|
||||
final ChatMessage message = event.getChatMessage();
|
||||
|
||||
if (i > 0 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
|
||||
EventLog previousEvent = (EventLog)getItem(i-1);
|
||||
if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||
ChatMessage previousMessage = previousEvent.getChatMessage();
|
||||
if (previousMessage.getFromAddress().weakEqual(message.getFromAddress())) {
|
||||
holder.separatorLayout.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
// No separator if previous event is not a message
|
||||
holder.separatorLayout.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
holder.messageId = message.getMessageId();
|
||||
message.setUserData(holder);
|
||||
|
||||
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;
|
||||
|
||||
LinphoneContact contact = null;
|
||||
if (message.isOutgoing()) {
|
||||
message.setListener(mListener);
|
||||
|
||||
if (status == ChatMessage.State.InProgress) {
|
||||
holder.messageSendingInProgress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!message.isSecured() && LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory && status != ChatMessage.State.InProgress) {
|
||||
holder.messageStatus.setVisibility(View.VISIBLE);
|
||||
holder.messageStatus.setImageResource(R.drawable.chat_unsecure);
|
||||
}
|
||||
|
||||
if (status == ChatMessage.State.Delivered) {
|
||||
/*holder.imdmLayout.setVisibility(View.VISIBLE);
|
||||
holder.imdmLabel.setText(R.string.sent);
|
||||
holder.imdmIcon.setImageResource(R.drawable.chat_delivered);
|
||||
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorD));*/
|
||||
} else 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.error);
|
||||
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI));
|
||||
} else if (status == ChatMessage.State.FileTransferError) {
|
||||
holder.imdmLayout.setVisibility(View.VISIBLE);
|
||||
holder.imdmIcon.setImageResource(R.drawable.chat_error);
|
||||
holder.imdmLabel.setText(R.string.file_transfer_error);
|
||||
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI));
|
||||
}
|
||||
|
||||
if (isEditionEnabled()) {
|
||||
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
|
||||
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
||||
} else {
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
||||
}
|
||||
|
||||
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 {
|
||||
for (LinphoneContact c : mParticipants) {
|
||||
if (c != null && c.hasAddress(remoteSender.asStringUriOnly())) {
|
||||
contact = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEditionEnabled()) {
|
||||
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
|
||||
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
||||
} else {
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
layoutParams.setMargins(0, MARGIN_BETWEEN_MESSAGES/2, SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (contact == null) {
|
||||
contact = ContactsManager.getInstance().findContactFromAddress(remoteSender);
|
||||
}
|
||||
if (contact != null) {
|
||||
if (contact.getFullName() != null) {
|
||||
displayName = contact.getFullName();
|
||||
} else {
|
||||
displayName = LinphoneUtils.getAddressDisplayName(remoteSender);
|
||||
}
|
||||
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
if (contact.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri());
|
||||
}
|
||||
} else {
|
||||
displayName = LinphoneUtils.getAddressDisplayName(remoteSender);
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
}
|
||||
holder.contactName.setText(LinphoneUtils.timestampToHumanDate(mContext, message.getTime(), R.string.messages_date_format) + " - " + displayName);
|
||||
|
||||
if (message.hasTextContent()) {
|
||||
String msg = message.getTextContent();
|
||||
Spanned text = LinphoneUtils.getTextWithHttpLinks(msg);
|
||||
holder.messageText.setText(text);
|
||||
holder.messageText.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
holder.messageText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
String externalBodyUrl = message.getExternalBodyUrl();
|
||||
Content fileTransferContent = message.getFileTransferInformation();
|
||||
|
||||
if (message.getAppdata() != null) { // Something to display
|
||||
displayAttachedFile(message, holder);
|
||||
}
|
||||
|
||||
if (externalBodyUrl != null) { // Incoming file transfer not yet downloaded
|
||||
holder.fileName.setVisibility(View.VISIBLE);
|
||||
holder.fileName.setText(fileTransferContent.getName());
|
||||
|
||||
holder.fileTransferLayout.setVisibility(View.VISIBLE);
|
||||
holder.fileTransferProgressBar.setVisibility(View.GONE);
|
||||
if (message.isFileTransferInProgress()) { // Incoming file transfer in progress
|
||||
holder.fileTransferAction.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.fileTransferAction.setText(mContext.getString(R.string.accept));
|
||||
holder.fileTransferAction.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mContext.getPackageManager().checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
|
||||
v.setEnabled(false);
|
||||
String filename = message.getFileTransferInformation().getName();
|
||||
File file = new File(Environment.getExternalStorageDirectory(), filename);
|
||||
int prefix = 1;
|
||||
while (file.exists()) {
|
||||
file = new File(Environment.getExternalStorageDirectory(), prefix + "_" + filename);
|
||||
Log.w("File with that name already exists, renamed to " + prefix + "_" + filename);
|
||||
prefix += 1;
|
||||
}
|
||||
message.setListener(mListener);
|
||||
message.setFileTransferFilepath(file.getPath());
|
||||
message.downloadFile();
|
||||
|
||||
} else {
|
||||
Log.w("WRITE_EXTERNAL_STORAGE permission not granted, won't be able to store the downloaded file");
|
||||
LinphoneActivity.instance().checkAndRequestExternalStoragePermission();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (message.isFileTransferInProgress()) { // Outgoing file transfer in progress
|
||||
message.setListener(mListener); // add the listener for file upload progress display
|
||||
holder.messageSendingInProgress.setVisibility(View.GONE);
|
||||
holder.fileTransferLayout.setVisibility(View.VISIBLE);
|
||||
holder.fileTransferAction.setText(mContext.getString(R.string.cancel));
|
||||
holder.fileTransferAction.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
message.cancelFileTransfer();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
holder.bubbleLayout.setLayoutParams(layoutParams);
|
||||
} else { // Event is not chat message
|
||||
holder.eventLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
Address address = event.getParticipantAddress();
|
||||
String displayName = null;
|
||||
if (address != null) {
|
||||
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
|
||||
if (contact != null) {
|
||||
displayName = contact.getFullName();
|
||||
} else {
|
||||
displayName = LinphoneUtils.getAddressDisplayName(address);
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.getType()) {
|
||||
case ConferenceCreated:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.conference_created));
|
||||
break;
|
||||
case ConferenceTerminated:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.conference_destroyed));
|
||||
break;
|
||||
case ConferenceParticipantAdded:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.participant_added).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantRemoved:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.participant_removed).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceSubjectChanged:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.subject_changed).replace("%s", event.getSubject()));
|
||||
break;
|
||||
case ConferenceParticipantSetAdmin:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.admin_set).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantUnsetAdmin:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.admin_unset).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantDeviceAdded:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.device_added).replace("%s", displayName));
|
||||
break;
|
||||
case ConferenceParticipantDeviceRemoved:
|
||||
holder.eventMessage.setText(mContext.getString(R.string.device_removed).replace("%s", displayName));
|
||||
break;
|
||||
case None:
|
||||
default:
|
||||
//TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void loadBitmap(String path, ImageView imageView) {
|
||||
if (cancelPotentialWork(path, imageView)) {
|
||||
if (LinphoneUtils.isExtensionImage(path)) {
|
||||
|
|
|
@ -20,68 +20,82 @@ 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.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.linphone.contacts.ContactsManager;
|
||||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.EventLog;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.ui.ListSelectionHelper;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.fragments.FragmentsAvailable;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.LinphoneManager;
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.contacts.ContactsManager;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.core.ChatMessage;
|
||||
import org.linphone.core.ChatRoom;
|
||||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.CoreListenerStub;
|
||||
import org.linphone.core.EventLog;
|
||||
import org.linphone.fragments.FragmentsAvailable;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
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;
|
||||
private TextView mNoChatHistory;
|
||||
public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ChatRoomsAdapter.ChatRoomViewHolder.ClickListener, SelectableHelper.DeleteListener {
|
||||
|
||||
private RecyclerView mChatRoomsList;
|
||||
private ImageView mNewDiscussionButton, mBackToCallButton;
|
||||
private ChatRoomsAdapter mChatRoomsAdapter;
|
||||
private CoreListenerStub mListener;
|
||||
private ListSelectionHelper mSelectionHelper;
|
||||
private RelativeLayout mWaitLayout;
|
||||
private int mChatRoomDeletionPendingCount;
|
||||
private ChatRoomListenerStub mChatRoomListener;
|
||||
private Context mContext;
|
||||
public List<ChatRoom> mRooms;
|
||||
private SelectableHelper mSelectionHelper;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
mInflater = inflater;
|
||||
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
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);
|
||||
|
||||
mChatRoomsList = view.findViewById(R.id.chatList);
|
||||
mWaitLayout = view.findViewById(R.id.waitScreen);
|
||||
mNewDiscussionButton = view.findViewById(R.id.new_discussion);
|
||||
mBackToCallButton = view.findViewById(R.id.back_in_call);
|
||||
|
||||
mSelectionHelper = new SelectableHelper(view, this);
|
||||
mChatRoomsAdapter = new ChatRoomsAdapter(mContext, R.layout.chatlist_cell, mRooms,this, mSelectionHelper);
|
||||
|
||||
mChatRoomsList.setAdapter(mChatRoomsAdapter);
|
||||
mSelectionHelper.setAdapter(mChatRoomsAdapter);
|
||||
mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog);
|
||||
|
||||
mWaitLayout = view.findViewById(R.id.waitScreen);
|
||||
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);
|
||||
mChatRoomsList.setLayoutManager(layoutManager);
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mChatRoomsList.getContext(),
|
||||
((LinearLayoutManager) layoutManager).getOrientation());
|
||||
dividerItemDecoration.setDrawable(getActivity().getApplicationContext().getResources().getDrawable(R.drawable.divider));
|
||||
mChatRoomsList.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
mWaitLayout.setVisibility(View.GONE);
|
||||
|
||||
mChatRoomsList = view.findViewById(R.id.chatList);
|
||||
mChatRoomsList.setAdapter(mChatRoomsAdapter);
|
||||
|
||||
mNoChatHistory = view.findViewById(R.id.noChatHistory);
|
||||
mNoChatHistory.setVisibility(View.GONE);
|
||||
|
||||
mNewDiscussionButton = view.findViewById(R.id.new_discussion);
|
||||
mNewDiscussionButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@ -89,7 +103,6 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
}
|
||||
});
|
||||
|
||||
mBackToCallButton = view.findViewById(R.id.back_in_call);
|
||||
mBackToCallButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@ -129,18 +142,36 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClicked(int position) {
|
||||
if (mChatRoomsAdapter.isEditionEnabled()) {
|
||||
mChatRoomsAdapter.toggleSelection(position);
|
||||
} else {
|
||||
ChatRoom room = (ChatRoom) mChatRoomsAdapter.getItem(position);
|
||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asString(),null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClicked(int position) {
|
||||
if (!mChatRoomsAdapter.isEditionEnabled()) {
|
||||
mSelectionHelper.enterEditionMode();
|
||||
}
|
||||
mChatRoomsAdapter.toggleSelection(position);
|
||||
return true;
|
||||
}
|
||||
|
||||
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(), null);
|
||||
} else {
|
||||
|
@ -156,7 +187,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()) {
|
||||
|
@ -181,6 +212,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
ContactsManager.removeContactsListener(this);
|
||||
mChatRoomsAdapter.clear();
|
||||
super.onPause();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -208,7 +240,6 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
if (mChatRoomDeletionPendingCount > 0) {
|
||||
mWaitLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
LinphoneActivity.instance().refreshMissedChatCountDisplay();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -218,9 +249,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
|
||||
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.notifyDataSetInvalidated();
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -21,8 +21,7 @@ package org.linphone.chat;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -37,13 +36,11 @@ 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.ChatRoomCapabilities;
|
||||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.EventLog;
|
||||
import org.linphone.ui.ListSelectionAdapter;
|
||||
import org.linphone.ui.ListSelectionHelper;
|
||||
import org.linphone.ui.SelectableAdapter;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -51,9 +48,9 @@ import java.util.Collections;
|
|||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ChatRoomsAdapter extends ListSelectionAdapter {
|
||||
public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomsAdapter.ChatRoomViewHolder> {
|
||||
|
||||
private class ChatRoomViewHolder {
|
||||
public static class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
|
||||
public TextView lastMessageSenderView;
|
||||
public TextView lastMessageView;
|
||||
public TextView date;
|
||||
|
@ -61,39 +58,133 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
|||
public TextView unreadMessages;
|
||||
public CheckBox delete;
|
||||
public ImageView contactPicture;
|
||||
public Context mContext;
|
||||
public ChatRoom mRoom;
|
||||
public ClickListener listener;
|
||||
|
||||
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, ClickListener listener) {
|
||||
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);
|
||||
this.listener = listener;
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
itemView.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
public void bindChatRoom(ChatRoom room) {
|
||||
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)));
|
||||
getAvatar(mRoom);
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (listener != null) {
|
||||
listener.onItemClicked(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onLongClick(View v) {
|
||||
if (listener != null) {
|
||||
return listener.onItemLongClicked(getAdapterPosition());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
return (LinphoneUtils.getAddressDisplayName(mRoom.getLastMessageInHistory().getFromAddress()) + ":");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getContact(ChatRoom mRoom) {
|
||||
Address contactAddress = mRoom.getPeerAddress();
|
||||
if (mRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) && mRoom.getParticipants().length > 0) {
|
||||
contactAddress = mRoom.getParticipants()[0].getAddress();
|
||||
}
|
||||
|
||||
if (mRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||
LinphoneContact contact;
|
||||
if (mRoom.getParticipants().length > 0) {
|
||||
contact = ContactsManager.getInstance().findContactFromAddress(mRoom.getParticipants()[0].getAddress());
|
||||
if (contact != null) {
|
||||
return (contact.getFullName());
|
||||
}
|
||||
return (LinphoneUtils.getAddressDisplayName(mRoom.getParticipants()[0].getAddress()));
|
||||
} else {
|
||||
contact = ContactsManager.getInstance().findContactFromAddress(contactAddress);
|
||||
if (contact != null) {
|
||||
return (contact.getFullName());
|
||||
}
|
||||
return (LinphoneUtils.getAddressDisplayName(contactAddress));
|
||||
}
|
||||
}
|
||||
return (mRoom.getSubject());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ClickListener {
|
||||
void onItemClicked(int position);
|
||||
boolean onItemLongClicked(int position);
|
||||
}
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private List<ChatRoom> mRooms;
|
||||
private LayoutInflater mLayoutInflater;
|
||||
private Bitmap mDefaultBitmap, mDefaultGroupBitmap;
|
||||
public List<ChatRoom> mRooms;
|
||||
private static Bitmap mDefaultBitmap;
|
||||
//private Bitmap mDefaultGroupBitmap;
|
||||
private ChatRoomListenerStub mListener;
|
||||
private int itemResource;
|
||||
private ChatRoomViewHolder.ClickListener clickListener;
|
||||
|
||||
public ChatRoomsAdapter(Context context, ListSelectionHelper helper, LayoutInflater inflater) {
|
||||
public ChatRoomsAdapter(Context context, int itemResource, List<ChatRoom> mRooms, ChatRoomViewHolder.ClickListener clickListener, SelectableHelper helper) {
|
||||
super(helper);
|
||||
mContext = context;
|
||||
mLayoutInflater = inflater;
|
||||
mRooms = new ArrayList<>();
|
||||
this.clickListener = clickListener;
|
||||
this.mRooms = mRooms;
|
||||
this.mContext = context;
|
||||
this.itemResource = itemResource;
|
||||
mDefaultBitmap = ContactsManager.getInstance().getDefaultAvatarBitmap();
|
||||
mDefaultGroupBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chat_group_avatar);
|
||||
//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());
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public ChatRoomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(this.itemResource, parent, false);
|
||||
return new ChatRoomViewHolder(this.mContext, view, clickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ChatRoomViewHolder holder, int position) {
|
||||
ChatRoom room = this.mRooms.get(position);
|
||||
holder.delete.setVisibility(this.isEditionEnabled() == true ? View.VISIBLE : View.INVISIBLE);
|
||||
holder.unreadMessages.setVisibility(this.isEditionEnabled() == false ? View.VISIBLE : View.INVISIBLE);
|
||||
holder.delete.setChecked(isSelected(position) ? true : false);
|
||||
holder.bindChatRoom(room);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
|
@ -114,6 +205,7 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
|||
room.removeListener(mListener);
|
||||
}
|
||||
mRooms.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,8 +213,8 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
|||
*/
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mRooms.size();
|
||||
public int getItemCount() {
|
||||
return this.mRooms.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,121 +226,4 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
|||
public long getItemId(int position) {
|
||||
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(), null);
|
||||
}
|
||||
});
|
||||
holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ import android.os.Bundle;
|
|||
import android.os.Environment;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.ContextMenu;
|
||||
|
@ -45,12 +47,10 @@ import android.view.ViewGroup;
|
|||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.linphone.LinphoneManager;
|
||||
|
@ -61,6 +61,7 @@ import org.linphone.activities.LinphoneActivity;
|
|||
import org.linphone.compatibility.Compatibility;
|
||||
import org.linphone.contacts.ContactAddress;
|
||||
import org.linphone.contacts.ContactsManager;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.contacts.LinphoneContact;
|
||||
import org.linphone.core.Address;
|
||||
import org.linphone.core.ChatMessage;
|
||||
|
@ -73,10 +74,9 @@ import org.linphone.core.EventLog;
|
|||
import org.linphone.core.Factory;
|
||||
import org.linphone.core.LimeState;
|
||||
import org.linphone.core.Participant;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.core.Reason;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.ui.ListSelectionHelper;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
@ -85,7 +85,7 @@ import java.util.List;
|
|||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||
import static org.linphone.fragments.FragmentsAvailable.CHAT;
|
||||
|
||||
public class GroupChatFragment extends Fragment implements ChatRoomListener, ContactsUpdatedListener, ListSelectionHelper.DeleteListener {
|
||||
public class GroupChatFragment extends Fragment implements ChatRoomListener, ContactsUpdatedListener, ChatBubbleViewHolder.ClickListener ,SelectableHelper.DeleteListener {
|
||||
private static final int ADD_PHOTO = 1337;
|
||||
|
||||
private ImageView mBackButton, mCallButton, mBackToCallButton, mGroupInfosButton;
|
||||
|
@ -93,10 +93,10 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
private TextView mRoomLabel, mParticipantsLabel, mRemoteComposing;
|
||||
private EditText mMessageTextToSend;
|
||||
private LayoutInflater mInflater;
|
||||
private ListView mChatEventsList;
|
||||
private RecyclerView mChatEventsList;
|
||||
private LinearLayout mFilesUploadLayout;
|
||||
private ListSelectionHelper mSelectionHelper;
|
||||
|
||||
private SelectableHelper mSelectionHelper;
|
||||
private Context mContext;
|
||||
private ViewTreeObserver.OnGlobalLayoutListener mKeyboardListener;
|
||||
private Uri mImageToUploadUri;
|
||||
private ChatEventsAdapter mEventsAdapter;
|
||||
|
@ -104,7 +104,8 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
private Address mRemoteSipAddress, mRemoteParticipantAddress;
|
||||
private ChatRoom mChatRoom;
|
||||
private ArrayList<LinphoneContact> mParticipants;
|
||||
|
||||
private LinearLayoutManager layoutManager;
|
||||
private int mContextMenuMessagePosition;
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -116,10 +117,9 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
mRemoteSipAddress = LinphoneManager.getLc().createAddress(mRemoteSipUri);
|
||||
}
|
||||
|
||||
mInflater = inflater;
|
||||
this.mContext = getActivity().getApplicationContext();
|
||||
View view = inflater.inflate(R.layout.chat, container, false);
|
||||
|
||||
mSelectionHelper = new ListSelectionHelper(view, this);
|
||||
|
||||
mBackButton = view.findViewById(R.id.back);
|
||||
mBackButton.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -213,7 +213,9 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
mRemoteComposing = view.findViewById(R.id.remote_composing);
|
||||
|
||||
mChatEventsList = view.findViewById(R.id.chat_message_list);
|
||||
registerForContextMenu(mChatEventsList);
|
||||
mSelectionHelper = new SelectableHelper(view, this);
|
||||
layoutManager = new LinearLayoutManager(mContext);
|
||||
mChatEventsList.setLayoutManager(layoutManager);
|
||||
|
||||
if (getArguments() != null) {
|
||||
String fileSharedUri = getArguments().getString("fileSharedUri");
|
||||
|
@ -233,7 +235,6 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
if (getArguments().getString("messageDraft") != null)
|
||||
mMessageTextToSend.setText(getArguments().getString("messageDraft"));
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -257,7 +258,6 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
initChatRoom();
|
||||
displayChatRoomHeader();
|
||||
displayChatRoomHistory();
|
||||
|
||||
LinphoneManager.getInstance().setCurrentChatRoomAddress(mRemoteSipAddress);
|
||||
}
|
||||
|
||||
|
@ -347,12 +347,15 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
|
||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
EventLog event = (EventLog) mEventsAdapter.getItem(info.position);
|
||||
ChatBubbleViewHolder holder = (ChatBubbleViewHolder) v.getTag();
|
||||
mContextMenuMessagePosition = holder.getAdapterPosition();
|
||||
|
||||
EventLog event = (EventLog) mEventsAdapter.getItem(mContextMenuMessagePosition);
|
||||
if (event.getType() != EventLog.Type.ConferenceChatMessage) {
|
||||
return;
|
||||
}
|
||||
|
@ -365,8 +368,8 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
inflater.inflate(R.menu.chat_bubble_menu, menu);
|
||||
}
|
||||
|
||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||
// Do not show messages' IDMN state in 1 to 1 chat room as it is already visible in the lower corner of the bubble
|
||||
if (!message.isOutgoing() && mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||
// Do not show incoming messages IDMN state in 1 to 1 chat room as we don't receive IMDN for them
|
||||
menu.removeItem(R.id.imdn_infos);
|
||||
}
|
||||
if (!message.hasTextContent()) {
|
||||
|
@ -377,9 +380,9 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
||||
|
||||
EventLog event = (EventLog) mEventsAdapter.getItem(info.position);
|
||||
EventLog event = (EventLog) mEventsAdapter.getItem(mContextMenuMessagePosition);
|
||||
|
||||
if (event.getType() != EventLog.Type.ConferenceChatMessage) {
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
@ -388,7 +391,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
String messageId = message.getMessageId();
|
||||
|
||||
if (item.getItemId() == R.id.resend) {
|
||||
mEventsAdapter.removeItem(info.position);
|
||||
mEventsAdapter.removeItem(mContextMenuMessagePosition);
|
||||
message.resend();
|
||||
return true;
|
||||
}
|
||||
|
@ -406,7 +409,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
}
|
||||
if (item.getItemId() == R.id.delete_message) {
|
||||
mChatRoom.deleteMessage(message);
|
||||
mEventsAdapter.removeItem(info.position);
|
||||
mEventsAdapter.removeItem(mContextMenuMessagePosition);
|
||||
return true;
|
||||
}
|
||||
return super.onContextItemSelected(item);
|
||||
|
@ -548,26 +551,33 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
|||
}
|
||||
|
||||
private void displayChatRoomHistory() {
|
||||
|
||||
if (mChatRoom == null) return;
|
||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||
mEventsAdapter = new ChatEventsAdapter(this, mSelectionHelper, mInflater, mChatRoom.getHistoryMessageEvents(0), mParticipants);
|
||||
mEventsAdapter = new ChatEventsAdapter(this, mSelectionHelper, R.layout.chat_bubble, mChatRoom.getHistoryMessageEvents(0), mParticipants, this);
|
||||
} else {
|
||||
mEventsAdapter = new ChatEventsAdapter(this, mSelectionHelper, mInflater, mChatRoom.getHistoryEvents(0), mParticipants);
|
||||
mEventsAdapter = new ChatEventsAdapter(this, mSelectionHelper, R.layout.chat_bubble, mChatRoom.getHistoryEvents(0), mParticipants, this);
|
||||
}
|
||||
mSelectionHelper.setAdapter(mEventsAdapter);
|
||||
mChatEventsList.setAdapter(mEventsAdapter);
|
||||
}
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
public void scrollToBottom() {
|
||||
if (((mChatEventsList.getLastVisiblePosition() >= (mEventsAdapter.getCount() - 1)) && (mChatEventsList.getFirstVisiblePosition() <= (mEventsAdapter.getCount() - 1)))) {
|
||||
mChatEventsList.setSelection(mEventsAdapter.getCount() - 1);
|
||||
}
|
||||
mChatEventsList.getLayoutManager().scrollToPosition(mEventsAdapter.getCount() - 1);
|
||||
}
|
||||
|
||||
public String getRemoteSipUri() {
|
||||
return mRemoteSipUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClicked(int position) {
|
||||
if (mEventsAdapter.isEditionEnabled()) {
|
||||
mEventsAdapter.toggleSelection(position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* File transfer related
|
||||
*/
|
||||
|
|
|
@ -19,6 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
package org.linphone.chat;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -32,35 +34,126 @@ import org.linphone.R;
|
|||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.contacts.ContactAddress;
|
||||
import org.linphone.contacts.LinphoneContact;
|
||||
import org.linphone.contacts.SearchContactsListAdapter;
|
||||
import org.linphone.core.ChatRoom;
|
||||
import org.linphone.core.Participant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GroupInfoAdapter extends BaseAdapter {
|
||||
private LayoutInflater mInflater;
|
||||
public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.ViewHolder> {
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder{
|
||||
public TextView name;
|
||||
public ImageView avatar;
|
||||
public ImageView delete;
|
||||
public LinearLayout isAdmin;
|
||||
public LinearLayout isNotAdmin;
|
||||
|
||||
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
name = view.findViewById(R.id.name);
|
||||
avatar = view.findViewById(R.id.contact_picture);
|
||||
delete = view.findViewById(R.id.delete);
|
||||
isAdmin = view.findViewById(R.id.isAdminLayout);
|
||||
isNotAdmin = view.findViewById(R.id.isNotAdminLayout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<ContactAddress> mItems;
|
||||
private View.OnClickListener mDeleteListener;
|
||||
private boolean mHideAdminFeatures;
|
||||
private ChatRoom mChatRoom;
|
||||
public ImageView avatar;
|
||||
|
||||
public GroupInfoAdapter(LayoutInflater inflater, List<ContactAddress> items, boolean hideAdminFeatures, boolean isCreation) {
|
||||
mInflater = inflater;
|
||||
public GroupInfoAdapter(List<ContactAddress> items, boolean hideAdminFeatures, boolean isCreation) {
|
||||
mItems = items;
|
||||
mHideAdminFeatures = hideAdminFeatures || isCreation;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_infos_cell, parent, false);
|
||||
return new ViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||
final ContactAddress ca = (ContactAddress)getItem(position);
|
||||
LinphoneContact c = ca.getContact();
|
||||
this.avatar=holder.avatar;
|
||||
holder.name.setText((c.getFullName() != null) ? c.getFullName() :
|
||||
(ca.getDisplayName() != null) ? ca.getDisplayName() : ca.getUsername());
|
||||
if (c.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), avatar, c.getThumbnailUri());
|
||||
}
|
||||
|
||||
holder.delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mDeleteListener != null) {
|
||||
mDeleteListener.onClick(view);
|
||||
}
|
||||
}
|
||||
});
|
||||
holder.delete.setTag(ca);
|
||||
|
||||
holder.isAdmin.setVisibility(ca.isAdmin() ? View.VISIBLE : View.GONE);
|
||||
holder.isNotAdmin.setVisibility(ca.isAdmin() ? View.GONE : View.VISIBLE);
|
||||
|
||||
holder.isAdmin.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
holder.isNotAdmin.setVisibility(View.VISIBLE);
|
||||
holder.isAdmin.setVisibility(View.GONE);
|
||||
ca.setAdmin(false);
|
||||
}
|
||||
});
|
||||
|
||||
holder.isNotAdmin.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
holder.isNotAdmin.setVisibility(View.GONE);
|
||||
holder.isAdmin.setVisibility(View.VISIBLE);
|
||||
ca.setAdmin(true);
|
||||
}
|
||||
});
|
||||
|
||||
holder.delete.setVisibility(View.VISIBLE);
|
||||
if (mHideAdminFeatures) {
|
||||
holder.delete.setVisibility(View.INVISIBLE);
|
||||
holder.isAdmin.setOnClickListener(null); // Do not allow not admin to remove it's rights but display admins
|
||||
holder.isNotAdmin.setVisibility(View.GONE); // Hide not admin button for not admin participants
|
||||
} else if (mChatRoom != null) {
|
||||
boolean found = false;
|
||||
for (Participant p : mChatRoom.getParticipants()) {
|
||||
if (p.getAddress().weakEqual(ca.getAddress())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
holder.isNotAdmin.setVisibility(View.GONE); // Hide not admin button for participant not yet added so even if user click it it won't have any effect
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
public void setChatRoom(ChatRoom room) {
|
||||
mChatRoom = room;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int i) {
|
||||
return mItems.get(i);
|
||||
}
|
||||
|
@ -70,79 +163,6 @@ public class GroupInfoAdapter extends BaseAdapter {
|
|||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
||||
if (view == null) {
|
||||
view = mInflater.inflate(R.layout.chat_infos_cell, null);
|
||||
}
|
||||
|
||||
final ContactAddress ca = (ContactAddress)getItem(i);
|
||||
LinphoneContact c = ca.getContact();
|
||||
|
||||
TextView name = view.findViewById(R.id.name);
|
||||
ImageView avatar = view.findViewById(R.id.contact_picture);
|
||||
ImageView delete = view.findViewById(R.id.delete);
|
||||
final LinearLayout isAdmin = view.findViewById(R.id.isAdminLayout);
|
||||
final LinearLayout isNotAdmin = view.findViewById(R.id.isNotAdminLayout);
|
||||
|
||||
name.setText((c.getFullName() != null) ? c.getFullName() :
|
||||
(ca.getDisplayName() != null) ? ca.getDisplayName() : ca.getUsername());
|
||||
if (c.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), avatar, c.getThumbnailUri());
|
||||
}
|
||||
|
||||
delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mDeleteListener != null) {
|
||||
mDeleteListener.onClick(view);
|
||||
}
|
||||
}
|
||||
});
|
||||
delete.setTag(ca);
|
||||
|
||||
isAdmin.setVisibility(ca.isAdmin() ? View.VISIBLE : View.GONE);
|
||||
isNotAdmin.setVisibility(ca.isAdmin() ? View.GONE : View.VISIBLE);
|
||||
|
||||
isAdmin.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
isNotAdmin.setVisibility(View.VISIBLE);
|
||||
isAdmin.setVisibility(View.GONE);
|
||||
ca.setAdmin(false);
|
||||
}
|
||||
});
|
||||
|
||||
isNotAdmin.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
isNotAdmin.setVisibility(View.GONE);
|
||||
isAdmin.setVisibility(View.VISIBLE);
|
||||
ca.setAdmin(true);
|
||||
}
|
||||
});
|
||||
|
||||
delete.setVisibility(View.VISIBLE);
|
||||
if (mHideAdminFeatures) {
|
||||
delete.setVisibility(View.INVISIBLE);
|
||||
isAdmin.setOnClickListener(null); // Do not allow not admin to remove it's rights but display admins
|
||||
isNotAdmin.setVisibility(View.GONE); // Hide not admin button for not admin participants
|
||||
} else if (mChatRoom != null) {
|
||||
boolean found = false;
|
||||
for (Participant p : mChatRoom.getParticipants()) {
|
||||
if (p.getAddress().weakEqual(ca.getAddress())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
isNotAdmin.setVisibility(View.GONE); // Hide not admin button for participant not yet added so even if user click it it won't have any effect
|
||||
}
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public void setOnDeleteClickListener(View.OnClickListener onClickListener) {
|
||||
mDeleteListener = onClickListener;
|
||||
}
|
||||
|
@ -154,6 +174,6 @@ public class GroupInfoAdapter extends BaseAdapter {
|
|||
|
||||
public void setAdminFeaturesVisible(boolean visible) {
|
||||
mHideAdminFeatures = !visible;
|
||||
notifyDataSetInvalidated();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,11 @@ package org.linphone.chat;
|
|||
|
||||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -32,7 +36,6 @@ import android.widget.Button;
|
|||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import org.linphone.LinphoneManager;
|
||||
|
@ -61,7 +64,9 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
|||
private Address mGroupChatRoomAddress;
|
||||
private EditText mSubjectField;
|
||||
private LayoutInflater mInflater;
|
||||
private ListView mParticipantsList;
|
||||
|
||||
private RecyclerView mParticipantsList;
|
||||
|
||||
private LinearLayout mLeaveGroupButton;
|
||||
private RelativeLayout mWaitLayout;
|
||||
private GroupInfoAdapter mAdapter;
|
||||
|
@ -73,6 +78,8 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
|||
private Dialog mAdminStateChangedDialog;
|
||||
private ChatRoomListenerStub mChatRoomCreationListener;
|
||||
private Bundle mShareInfos;
|
||||
private Context mContext;
|
||||
private LinearLayoutManager layoutManager;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
@ -82,6 +89,8 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
|||
if (getArguments() == null || getArguments().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
this.mContext = getActivity().getApplicationContext();
|
||||
|
||||
mParticipants = (ArrayList<ContactAddress>) getArguments().getSerializable("ContactAddress");
|
||||
|
||||
mGroupChatRoomAddress = null;
|
||||
|
@ -105,7 +114,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
|||
}
|
||||
|
||||
mParticipantsList = view.findViewById(R.id.chat_room_participants);
|
||||
mAdapter = new GroupInfoAdapter(mInflater, mParticipants, !mIsEditionEnabled, !mIsAlreadyCreatedGroup);
|
||||
mAdapter = new GroupInfoAdapter(mParticipants, !mIsEditionEnabled, !mIsAlreadyCreatedGroup);
|
||||
mAdapter.setOnDeleteClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
@ -118,6 +127,15 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
|||
});
|
||||
mParticipantsList.setAdapter(mAdapter);
|
||||
mAdapter.setChatRoom(mChatRoom);
|
||||
layoutManager = new LinearLayoutManager(mContext);
|
||||
mParticipantsList.setLayoutManager(layoutManager);
|
||||
|
||||
//Divider between items
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mParticipantsList.getContext(),
|
||||
layoutManager.getOrientation());
|
||||
dividerItemDecoration.setDrawable(mContext.getResources().getDrawable(R.drawable.divider));
|
||||
mParticipantsList.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
|
||||
String fileSharedUri = getArguments().getString("fileSharedUri");
|
||||
String messageDraft = getArguments().getString("messageDraft");
|
||||
|
|
|
@ -47,7 +47,7 @@ import org.linphone.core.ChatRoom;
|
|||
import org.linphone.core.Core;
|
||||
import org.linphone.core.ParticipantImdnState;
|
||||
|
||||
public class ImdnFragment extends Fragment {
|
||||
public class ImdnFragment extends Fragment{
|
||||
private LayoutInflater mInflater;
|
||||
private LinearLayout mRead, mReadHeader, mDelivered, mDeliveredHeader, mSent, mSentHeader, mUndelivered, mUndeliveredHeader;
|
||||
private ImageView mBackButton;
|
||||
|
|
219
src/android/org/linphone/contacts/ContactsListAdapter.java
Normal file
219
src/android/org/linphone/contacts/ContactsListAdapter.java
Normal file
|
@ -0,0 +1,219 @@
|
|||
package org.linphone.contacts;
|
||||
|
||||
/*
|
||||
ContactsListAdapter.java
|
||||
Copyright (C) 2018 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.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
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.LinearLayout;
|
||||
import android.widget.SectionIndexer;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.linphone.LinphoneUtils;
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.ui.SelectableAdapter;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContactsListAdapter extends SelectableAdapter<ContactsListAdapter.ViewHolder> implements SectionIndexer {
|
||||
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
|
||||
public CheckBox delete;
|
||||
public ImageView linphoneFriend;
|
||||
public TextView name;
|
||||
public LinearLayout separator;
|
||||
public TextView separatorText;
|
||||
public ImageView contactPicture;
|
||||
public TextView organization;
|
||||
//public ImageView friendStatus;
|
||||
private ClickListener listener;
|
||||
|
||||
private ViewHolder(View view, ClickListener listener) {
|
||||
super(view);
|
||||
|
||||
delete = (CheckBox) view.findViewById(R.id.delete);
|
||||
linphoneFriend = (ImageView) view.findViewById(R.id.friendLinphone);
|
||||
name = (TextView) view.findViewById(R.id.name);
|
||||
separator = (LinearLayout) view.findViewById(R.id.separator);
|
||||
separatorText = (TextView) view.findViewById(R.id.separator_text);
|
||||
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
|
||||
organization = (TextView) view.findViewById(R.id.contactOrganization);
|
||||
//friendStatus = (ImageView) view.findViewById(R.id.friendStatus);
|
||||
this.listener= listener;
|
||||
view.setOnClickListener(this);
|
||||
view.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (listener != null) {
|
||||
listener.onItemClicked(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onLongClick(View v) {
|
||||
if (listener != null) {
|
||||
return listener.onItemLongClicked(getAdapterPosition());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface ClickListener {
|
||||
void onItemClicked(int position);
|
||||
boolean onItemLongClicked(int position);
|
||||
}
|
||||
}
|
||||
|
||||
private List<LinphoneContact> mContacts;
|
||||
private String[] mSections;
|
||||
private ArrayList<String> mSectionsList;
|
||||
private Map<String, Integer> mMap = new LinkedHashMap<String, Integer>();
|
||||
private ViewHolder.ClickListener mClickListener;
|
||||
private Context mContext;
|
||||
private boolean mIsSearchMode;
|
||||
|
||||
ContactsListAdapter(Context context, List<LinphoneContact> contactsList, ViewHolder.ClickListener clickListener, SelectableHelper helper) {
|
||||
super(helper);
|
||||
mContext = context;
|
||||
updateDataSet(contactsList);
|
||||
mClickListener = clickListener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_cell, parent, false);
|
||||
return new ViewHolder(v, mClickListener);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
|
||||
LinphoneContact contact = (LinphoneContact) getItem(position);
|
||||
|
||||
holder.name.setText(contact.getFullName());
|
||||
|
||||
if (!mIsSearchMode) {
|
||||
String fullName = contact.getFullName();
|
||||
if (fullName != null && !fullName.isEmpty()) {
|
||||
holder.separatorText.setText(String.valueOf(fullName.charAt(0)));
|
||||
}
|
||||
}
|
||||
holder.separator.setVisibility(mIsSearchMode || (!mIsSearchMode && getPositionForSection(getSectionForPosition(position)) != position ) ? View.GONE:View.VISIBLE);
|
||||
holder.linphoneFriend.setVisibility(contact.isInFriendList() ? View.VISIBLE:View.GONE);
|
||||
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
if (contact.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri());
|
||||
}
|
||||
|
||||
boolean isOrgVisible = mContext.getResources().getBoolean(R.bool.display_contact_organization);
|
||||
String org = contact.getOrganization();
|
||||
if (org != null && !org.isEmpty() && isOrgVisible) {
|
||||
holder.organization.setText(org);
|
||||
holder.organization.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.organization.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
holder.delete.setVisibility(this.isEditionEnabled() ? View.VISIBLE : View.INVISIBLE);
|
||||
holder.delete.setChecked(isSelected(position));
|
||||
|
||||
}
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mContacts.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
if (position >= getItemCount()) return null;
|
||||
return mContacts.get(position);
|
||||
}
|
||||
|
||||
public void setmIsSearchMode(boolean set){
|
||||
mIsSearchMode = set;
|
||||
}
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void updateDataSet(List<LinphoneContact> contactsList) {
|
||||
mContacts = contactsList;
|
||||
|
||||
mMap = new LinkedHashMap<String, Integer>();
|
||||
String prevLetter = null;
|
||||
for (int i = 0; i < mContacts.size(); i++) {
|
||||
LinphoneContact contact = mContacts.get(i);
|
||||
String fullName = contact.getFullName();
|
||||
if (fullName == null || fullName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String firstLetter = fullName.substring(0, 1).toUpperCase(Locale.getDefault());
|
||||
if (!firstLetter.equals(prevLetter)) {
|
||||
prevLetter = firstLetter;
|
||||
mMap.put(firstLetter, i);
|
||||
}
|
||||
}
|
||||
mSectionsList = new ArrayList<String>(mMap.keySet());
|
||||
mSections = new String[mSectionsList.size()];
|
||||
mSectionsList.toArray(mSections);
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getSections() {
|
||||
return mSections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionForSection(int sectionIndex) {
|
||||
if (sectionIndex >= mSections.length || sectionIndex < 0) {
|
||||
return 0;
|
||||
}
|
||||
return mMap.get(mSections[sectionIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSectionForPosition(int position) {
|
||||
if (position >= mContacts.size() || position < 0) {
|
||||
return 0;
|
||||
}
|
||||
LinphoneContact contact = mContacts.get(position);
|
||||
String fullName = contact.getFullName();
|
||||
if (fullName == null || fullName.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
String letter = fullName.substring(0, 1).toUpperCase(Locale.getDefault());
|
||||
return mSectionsList.indexOf(letter);
|
||||
}
|
||||
}
|
|
@ -20,61 +20,55 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
*/
|
||||
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.SectionIndexer;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.linphone.fragments.FragmentsAvailable;
|
||||
import org.linphone.LinphoneManager;
|
||||
import org.linphone.LinphoneUtils;
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.fragments.FragmentsAvailable;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContactsListFragment extends Fragment implements OnClickListener, OnItemClickListener, ContactsUpdatedListener {
|
||||
private LayoutInflater mInflater;
|
||||
private ListView contactsList;
|
||||
public class ContactsListFragment extends Fragment implements OnItemClickListener, ContactsUpdatedListener, ContactsListAdapter.ViewHolder.ClickListener ,SelectableHelper.DeleteListener {
|
||||
private RecyclerView contactsList;
|
||||
private TextView noSipContact, noContact;
|
||||
private ImageView allContacts, linphoneContacts, newContact, edit, selectAll, deselectAll, delete, cancel;
|
||||
private boolean onlyDisplayLinphoneContacts, isEditMode, isSearchMode;
|
||||
private ImageView allContacts, linphoneContacts, newContact, edit;
|
||||
private boolean onlyDisplayLinphoneContacts;
|
||||
private View allContactsSelected, linphoneContactsSelected;
|
||||
private LinearLayout editList, topbar;
|
||||
private int lastKnownPosition;
|
||||
private boolean editOnClick = false, editConsumed = false, onlyDisplayChatAddress = false;
|
||||
private String sipAddressToAdd, displayName = null;
|
||||
private ImageView clearSearchField;
|
||||
private EditText searchField;
|
||||
private ProgressBar contactsFetchInProgress;
|
||||
private LinearLayoutManager layoutManager;
|
||||
private Context mContext;
|
||||
private SelectableHelper mSelectionHelper;
|
||||
private ContactsListAdapter mContactAdapter;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
mInflater = inflater;
|
||||
View view = inflater.inflate(R.layout.contacts_list, container, false);
|
||||
mContext = getActivity().getApplicationContext();
|
||||
mSelectionHelper = new SelectableHelper(view, this);
|
||||
|
||||
if (getArguments() != null) {
|
||||
editOnClick = getArguments().getBoolean("EditOnClick");
|
||||
|
@ -86,46 +80,64 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
|||
|
||||
noSipContact = (TextView) view.findViewById(R.id.noSipContact);
|
||||
noContact = (TextView) view.findViewById(R.id.noContact);
|
||||
|
||||
contactsList = (ListView) view.findViewById(R.id.contactsList);
|
||||
contactsList.setOnItemClickListener(this);
|
||||
contactsList = view.findViewById(R.id.contactsList);
|
||||
|
||||
allContacts = (ImageView) view.findViewById(R.id.all_contacts);
|
||||
allContacts.setOnClickListener(this);
|
||||
|
||||
linphoneContacts = (ImageView) view.findViewById(R.id.linphone_contacts);
|
||||
linphoneContacts.setOnClickListener(this);
|
||||
|
||||
linphoneContacts = (ImageView) view.findViewById(R.id.linphone_contacts);
|
||||
allContactsSelected = view.findViewById(R.id.all_contacts_select);
|
||||
linphoneContactsSelected = view.findViewById(R.id.linphone_contacts_select);
|
||||
edit = (ImageView) view.findViewById(R.id.edit);
|
||||
contactsFetchInProgress = (ProgressBar) view.findViewById(R.id.contactsFetchInProgress);
|
||||
newContact = (ImageView) view.findViewById(R.id.newContact);
|
||||
|
||||
allContacts.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onlyDisplayLinphoneContacts = false;
|
||||
allContactsSelected.setVisibility(View.VISIBLE);
|
||||
allContacts.setEnabled(false);
|
||||
linphoneContacts.setEnabled(true);
|
||||
linphoneContactsSelected.setVisibility(View.INVISIBLE);
|
||||
changeContactsAdapter();
|
||||
}
|
||||
});
|
||||
|
||||
linphoneContacts.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
allContactsSelected.setVisibility(View.INVISIBLE);
|
||||
linphoneContactsSelected.setVisibility(View.VISIBLE);
|
||||
linphoneContacts.setEnabled(false);
|
||||
allContacts.setEnabled(true);
|
||||
onlyDisplayLinphoneContacts = true;
|
||||
changeContactsAdapter();
|
||||
}
|
||||
});
|
||||
|
||||
newContact.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
editConsumed = true;
|
||||
if(displayName != null)
|
||||
LinphoneActivity.instance().addContact(displayName, sipAddressToAdd);
|
||||
else
|
||||
LinphoneActivity.instance().addContact(null, sipAddressToAdd);
|
||||
}
|
||||
});
|
||||
|
||||
newContact = (ImageView) view.findViewById(R.id.newContact);
|
||||
newContact.setOnClickListener(this);
|
||||
newContact.setEnabled(LinphoneManager.getLc().getCallsNb() == 0);
|
||||
|
||||
allContacts.setEnabled(onlyDisplayLinphoneContacts);
|
||||
linphoneContacts.setEnabled(!allContacts.isEnabled());
|
||||
contactsFetchInProgress.setVisibility(View.VISIBLE);
|
||||
|
||||
selectAll = (ImageView) view.findViewById(R.id.select_all);
|
||||
selectAll.setOnClickListener(this);
|
||||
|
||||
deselectAll = (ImageView) view.findViewById(R.id.deselect_all);
|
||||
deselectAll.setOnClickListener(this);
|
||||
|
||||
delete = (ImageView) view.findViewById(R.id.delete);
|
||||
delete.setOnClickListener(this);
|
||||
|
||||
editList = (LinearLayout) view.findViewById(R.id.edit_list);
|
||||
topbar = (LinearLayout) view.findViewById(R.id.top_bar);
|
||||
|
||||
cancel = (ImageView) view.findViewById(R.id.cancel);
|
||||
cancel.setOnClickListener(this);
|
||||
|
||||
edit = (ImageView) view.findViewById(R.id.edit);
|
||||
edit.setOnClickListener(this);
|
||||
|
||||
clearSearchField = (ImageView) view.findViewById(R.id.clearSearchField);
|
||||
clearSearchField.setOnClickListener(this);
|
||||
clearSearchField.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
searchField.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
searchField = (EditText) view.findViewById(R.id.searchField);
|
||||
searchField.addTextChangedListener(new TextWatcher() {
|
||||
|
@ -146,220 +158,103 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
|||
}
|
||||
});
|
||||
|
||||
layoutManager = new LinearLayoutManager(mContext);
|
||||
contactsList.setLayoutManager(layoutManager);
|
||||
|
||||
//Divider between items
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(contactsList.getContext(),
|
||||
layoutManager.getOrientation());
|
||||
dividerItemDecoration.setDrawable(getActivity().getResources().getDrawable(R.drawable.divider));
|
||||
contactsList.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
contactsFetchInProgress = (ProgressBar) view.findViewById(R.id.contactsFetchInProgress);
|
||||
contactsFetchInProgress.setVisibility(View.VISIBLE);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public int getNbItemsChecked(){
|
||||
int size = contactsList.getAdapter().getCount();
|
||||
int nb = 0;
|
||||
for(int i=0; i<size; i++) {
|
||||
if(contactsList.isItemChecked(i)) {
|
||||
nb ++;
|
||||
}
|
||||
}
|
||||
return nb;
|
||||
}
|
||||
|
||||
public void enabledDeleteButton(Boolean enabled){
|
||||
if(enabled){
|
||||
delete.setEnabled(true);
|
||||
} else {
|
||||
if (getNbItemsChecked() == 0){
|
||||
delete.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
|
||||
if (id == R.id.select_all) {
|
||||
deselectAll.setVisibility(View.VISIBLE);
|
||||
selectAll.setVisibility(View.GONE);
|
||||
enabledDeleteButton(true);
|
||||
selectAllList(true);
|
||||
return;
|
||||
}
|
||||
if (id == R.id.deselect_all) {
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
enabledDeleteButton(false);
|
||||
selectAllList(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == R.id.cancel) {
|
||||
quitEditMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == R.id.delete) {
|
||||
final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.delete_text));
|
||||
Button delete = (Button) dialog.findViewById(R.id.delete_button);
|
||||
Button cancel = (Button) dialog.findViewById(R.id.cancel);
|
||||
|
||||
delete.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
removeContacts();
|
||||
dialog.dismiss();
|
||||
quitEditMode();
|
||||
}
|
||||
});
|
||||
|
||||
cancel.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dialog.dismiss();
|
||||
quitEditMode();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == R.id.edit) {
|
||||
editList.setVisibility(View.VISIBLE);
|
||||
topbar.setVisibility(View.GONE);
|
||||
enabledDeleteButton(false);
|
||||
isEditMode = true;
|
||||
}
|
||||
|
||||
if (id == R.id.all_contacts) {
|
||||
onlyDisplayLinphoneContacts = false;
|
||||
allContactsSelected.setVisibility(View.VISIBLE);
|
||||
allContacts.setEnabled(false);
|
||||
linphoneContacts.setEnabled(true);
|
||||
linphoneContactsSelected.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
else if (id == R.id.linphone_contacts) {
|
||||
allContactsSelected.setVisibility(View.INVISIBLE);
|
||||
linphoneContactsSelected.setVisibility(View.VISIBLE);
|
||||
linphoneContacts.setEnabled(false);
|
||||
allContacts.setEnabled(true);
|
||||
onlyDisplayLinphoneContacts = true;
|
||||
|
||||
}
|
||||
|
||||
if(isEditMode){
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (searchField.getText().toString().length() > 0) {
|
||||
searchContacts();
|
||||
} else {
|
||||
changeContactsAdapter();
|
||||
}
|
||||
|
||||
if (id == R.id.newContact) {
|
||||
editConsumed = true;
|
||||
if(displayName != null)
|
||||
LinphoneActivity.instance().addContact(displayName, sipAddressToAdd);
|
||||
else
|
||||
LinphoneActivity.instance().addContact(null, sipAddressToAdd);
|
||||
}
|
||||
else if (id == R.id.clearSearchField) {
|
||||
searchField.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
private void selectAllList(boolean isSelectAll){
|
||||
int size = contactsList.getAdapter().getCount();
|
||||
for(int i=0; i<size; i++) {
|
||||
contactsList.setItemChecked(i,isSelectAll);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeContacts() {
|
||||
ArrayList<String> ids = new ArrayList<String>();
|
||||
int size = contactsList.getAdapter().getCount();
|
||||
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
if (contactsList.isItemChecked(i)) {
|
||||
LinphoneContact contact = (LinphoneContact) contactsList.getAdapter().getItem(i);
|
||||
if (contact.isAndroidContact()) {
|
||||
contact.deleteFriend();
|
||||
ids.add(contact.getAndroidId());
|
||||
} else {
|
||||
contact.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContactsManager.getInstance().deleteMultipleContactsAtOnce(ids);
|
||||
}
|
||||
|
||||
public void quitEditMode(){
|
||||
isEditMode = false;
|
||||
editList.setVisibility(View.GONE);
|
||||
topbar.setVisibility(View.VISIBLE);
|
||||
invalidate();
|
||||
if(getResources().getBoolean(R.bool.isTablet)){
|
||||
displayFirstContact();
|
||||
}
|
||||
}
|
||||
|
||||
public void displayFirstContact(){
|
||||
if (contactsList != null && contactsList.getAdapter() != null && contactsList.getAdapter().getCount() > 0) {
|
||||
LinphoneActivity.instance().displayContact((LinphoneContact) contactsList.getAdapter().getItem(0), false);
|
||||
if (contactsList != null && contactsList.getAdapter() != null && contactsList.getAdapter().getItemCount() > 0) {
|
||||
ContactsListAdapter mAdapt = (ContactsListAdapter)contactsList.getAdapter();
|
||||
LinphoneActivity.instance().displayContact((LinphoneContact) mAdapt.getItem(0), false);
|
||||
} else {
|
||||
LinphoneActivity.instance().displayEmptyFragment();
|
||||
}
|
||||
}
|
||||
|
||||
private void searchContacts() {
|
||||
searchContacts(searchField.getText().toString());
|
||||
}
|
||||
|
||||
private void searchContacts(String search) {
|
||||
boolean isEditionEnabled = false;
|
||||
if (search == null || search.length() == 0) {
|
||||
changeContactsAdapter();
|
||||
return;
|
||||
}
|
||||
changeContactsToggle();
|
||||
mContactAdapter.setmIsSearchMode(true);
|
||||
|
||||
isSearchMode = true;
|
||||
List<LinphoneContact> listContact;
|
||||
|
||||
if (onlyDisplayLinphoneContacts) {
|
||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
contactsList.setAdapter(new ContactsListAdapter(ContactsManager.getInstance().getSIPContacts(search)));
|
||||
listContact = ContactsManager.getInstance().getSIPContacts(search);
|
||||
} else {
|
||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
contactsList.setAdapter(new ContactsListAdapter(ContactsManager.getInstance().getContacts(search)));
|
||||
listContact = ContactsManager.getInstance().getContacts(search);
|
||||
}
|
||||
if(mContactAdapter != null && mContactAdapter.isEditionEnabled()) {
|
||||
isEditionEnabled=true;
|
||||
}
|
||||
|
||||
|
||||
mContactAdapter = new ContactsListAdapter(mContext, listContact, this, mSelectionHelper);
|
||||
|
||||
// contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
mSelectionHelper.setAdapter(mContactAdapter);
|
||||
if(isEditionEnabled) {
|
||||
mSelectionHelper.enterEditionMode();
|
||||
}
|
||||
contactsList.setAdapter(mContactAdapter);
|
||||
}
|
||||
|
||||
|
||||
private void changeContactsAdapter() {
|
||||
changeContactsToggle();
|
||||
List<LinphoneContact> listContact;
|
||||
|
||||
isSearchMode = false;
|
||||
noSipContact.setVisibility(View.GONE);
|
||||
noContact.setVisibility(View.GONE);
|
||||
contactsList.setVisibility(View.VISIBLE);
|
||||
boolean isEditionEnabled = false;
|
||||
if(searchField.getText().toString() == "") {
|
||||
if (onlyDisplayLinphoneContacts) {
|
||||
listContact = ContactsManager.getInstance().getSIPContacts();
|
||||
} else {
|
||||
listContact = ContactsManager.getInstance().getContacts();
|
||||
}
|
||||
|
||||
ContactsListAdapter adapter;
|
||||
contactsList.setFastScrollEnabled(false);
|
||||
if (onlyDisplayLinphoneContacts) {
|
||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
adapter = new ContactsListAdapter(ContactsManager.getInstance().getSIPContacts());
|
||||
contactsList.setAdapter(adapter);
|
||||
edit.setEnabled(true);
|
||||
} else {
|
||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
adapter = new ContactsListAdapter(ContactsManager.getInstance().getContacts());
|
||||
contactsList.setAdapter(adapter);
|
||||
edit.setEnabled(true);
|
||||
|
||||
}else{
|
||||
if (onlyDisplayLinphoneContacts) {
|
||||
listContact = ContactsManager.getInstance().getSIPContacts(searchField.getText().toString());
|
||||
} else {
|
||||
listContact = ContactsManager.getInstance().getContacts(searchField.getText().toString());
|
||||
}
|
||||
}
|
||||
contactsList.setFastScrollEnabled(true);
|
||||
adapter.notifyDataSetInvalidated();
|
||||
|
||||
if(mContactAdapter != null && mContactAdapter.isEditionEnabled()) {
|
||||
isEditionEnabled=true;
|
||||
}
|
||||
|
||||
if (adapter.getCount() > 0) {
|
||||
mContactAdapter = new ContactsListAdapter(mContext, listContact, this, mSelectionHelper);
|
||||
|
||||
mSelectionHelper.setAdapter(mContactAdapter);
|
||||
|
||||
if(isEditionEnabled) {
|
||||
mSelectionHelper.enterEditionMode();
|
||||
}
|
||||
contactsList.setAdapter(mContactAdapter);
|
||||
edit.setEnabled(true);
|
||||
|
||||
mContactAdapter.notifyDataSetChanged();
|
||||
|
||||
if (mContactAdapter.getItemCount() > 0) {
|
||||
contactsFetchInProgress.setVisibility(View.GONE);
|
||||
}
|
||||
ContactsManager.getInstance().setLinphoneContactsPrefered(onlyDisplayLinphoneContacts);
|
||||
|
@ -386,11 +281,36 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
|||
editConsumed = true;
|
||||
LinphoneActivity.instance().editContact(contact, sipAddressToAdd);
|
||||
} else {
|
||||
lastKnownPosition = contactsList.getFirstVisiblePosition();
|
||||
lastKnownPosition = layoutManager.findFirstVisibleItemPosition();
|
||||
LinphoneActivity.instance().displayContact(contact, onlyDisplayChatAddress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClicked(int position) {
|
||||
LinphoneContact contact = (LinphoneContact) mContactAdapter.getItem(position);
|
||||
|
||||
if (mContactAdapter.isEditionEnabled()) {
|
||||
mContactAdapter.toggleSelection(position);
|
||||
|
||||
} else if (editOnClick) {
|
||||
editConsumed = true;
|
||||
LinphoneActivity.instance().editContact(contact, sipAddressToAdd);
|
||||
} else {
|
||||
lastKnownPosition = layoutManager.findFirstVisibleItemPosition();
|
||||
LinphoneActivity.instance().displayContact(contact, onlyDisplayChatAddress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClicked(int position) {
|
||||
if (!mContactAdapter.isEditionEnabled()) {
|
||||
mSelectionHelper.enterEditionMode();
|
||||
}
|
||||
mContactAdapter.toggleSelection(position);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -426,13 +346,11 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
|||
return;
|
||||
ContactsListAdapter adapter = (ContactsListAdapter)contactsList.getAdapter();
|
||||
if (adapter != null) {
|
||||
contactsList.setFastScrollEnabled(false);
|
||||
if (onlyDisplayLinphoneContacts) {
|
||||
adapter.updateDataSet(ContactsManager.getInstance().getSIPContacts());
|
||||
} else {
|
||||
adapter.updateDataSet(ContactsManager.getInstance().getContacts());
|
||||
}
|
||||
contactsList.setFastScrollEnabled(true);
|
||||
contactsFetchInProgress.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
@ -443,206 +361,22 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
|||
} else {
|
||||
changeContactsAdapter();
|
||||
}
|
||||
contactsList.setSelectionFromTop(lastKnownPosition, 0);
|
||||
contactsList.scrollToPosition(lastKnownPosition);
|
||||
}
|
||||
|
||||
class ContactsListAdapter extends BaseAdapter implements SectionIndexer {
|
||||
private class ViewHolder {
|
||||
public CheckBox delete;
|
||||
public ImageView linphoneFriend;
|
||||
public TextView name;
|
||||
public LinearLayout separator;
|
||||
public TextView separatorText;
|
||||
public ImageView contactPicture;
|
||||
public TextView organization;
|
||||
//public ImageView friendStatus;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
delete = (CheckBox) view.findViewById(R.id.delete);
|
||||
linphoneFriend = (ImageView) view.findViewById(R.id.friendLinphone);
|
||||
name = (TextView) view.findViewById(R.id.name);
|
||||
separator = (LinearLayout) view.findViewById(R.id.separator);
|
||||
separatorText = (TextView) view.findViewById(R.id.separator_text);
|
||||
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
|
||||
organization = (TextView) view.findViewById(R.id.contactOrganization);
|
||||
//friendStatus = (ImageView) view.findViewById(R.id.friendStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private List<LinphoneContact> contacts;
|
||||
String[] sections;
|
||||
ArrayList<String> sectionsList;
|
||||
Map<String, Integer>map = new LinkedHashMap<String, Integer>();
|
||||
|
||||
ContactsListAdapter(List<LinphoneContact> contactsList) {
|
||||
updateDataSet(contactsList);
|
||||
}
|
||||
|
||||
public void updateDataSet(List<LinphoneContact> contactsList) {
|
||||
contacts = contactsList;
|
||||
|
||||
map = new LinkedHashMap<String, Integer>();
|
||||
String prevLetter = null;
|
||||
for (int i = 0; i < contacts.size(); i++) {
|
||||
LinphoneContact contact = contacts.get(i);
|
||||
String fullName = contact.getFullName();
|
||||
if (fullName == null || fullName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String firstLetter = fullName.substring(0, 1).toUpperCase(Locale.getDefault());
|
||||
if (!firstLetter.equals(prevLetter)) {
|
||||
prevLetter = firstLetter;
|
||||
map.put(firstLetter, i);
|
||||
}
|
||||
}
|
||||
sectionsList = new ArrayList<String>(map.keySet());
|
||||
sections = new String[sectionsList.size()];
|
||||
sectionsList.toArray(sections);
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return contacts.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
if (position >= getCount()) return null;
|
||||
return contacts.get(position);
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
View view = null;
|
||||
LinphoneContact contact = (LinphoneContact) getItem(position);
|
||||
if (contact == null) return null;
|
||||
|
||||
ViewHolder holder = null;
|
||||
if (convertView != null) {
|
||||
view = convertView;
|
||||
holder = (ViewHolder) view.getTag();
|
||||
} else {
|
||||
view = mInflater.inflate(R.layout.contact_cell, parent, false);
|
||||
holder = new ViewHolder(view);
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
holder.name.setText(contact.getFullName());
|
||||
|
||||
if (!isSearchMode) {
|
||||
if (getPositionForSection(getSectionForPosition(position)) != position) {
|
||||
holder.separator.setVisibility(View.GONE);
|
||||
@Override
|
||||
public void onDeleteSelection(Object[] objectsToDelete) {
|
||||
ArrayList<String> ids = new ArrayList<String>();
|
||||
int size = mContactAdapter.getSelectedItemCount();
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
LinphoneContact contact = (LinphoneContact)objectsToDelete[i];
|
||||
if (contact.isAndroidContact()) {
|
||||
contact.deleteFriend();
|
||||
ids.add(contact.getAndroidId());
|
||||
} else {
|
||||
holder.separator.setVisibility(View.VISIBLE);
|
||||
String fullName = contact.getFullName();
|
||||
if (fullName != null && !fullName.isEmpty()) {
|
||||
holder.separatorText.setText(String.valueOf(fullName.charAt(0)));
|
||||
}
|
||||
contact.delete();
|
||||
}
|
||||
} else {
|
||||
holder.separator.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (contact.isInFriendList()) {
|
||||
holder.linphoneFriend.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.linphoneFriend.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
if (contact.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, contact.getThumbnailUri());
|
||||
}
|
||||
|
||||
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
|
||||
String org = contact.getOrganization();
|
||||
if (org != null && !org.isEmpty() && isOrgVisible) {
|
||||
holder.organization.setText(org);
|
||||
holder.organization.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.organization.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (isEditMode) {
|
||||
holder.delete.setVisibility(View.VISIBLE);
|
||||
holder.delete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
contactsList.setItemChecked(position, b);
|
||||
if(getNbItemsChecked() == getCount()){
|
||||
deselectAll.setVisibility(View.VISIBLE);
|
||||
selectAll.setVisibility(View.GONE);
|
||||
enabledDeleteButton(true);
|
||||
} else {
|
||||
if(getNbItemsChecked() == 0){
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
enabledDeleteButton(false);
|
||||
} else {
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
enabledDeleteButton(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (contactsList.isItemChecked(position)) {
|
||||
holder.delete.setChecked(true);
|
||||
} else {
|
||||
holder.delete.setChecked(false);
|
||||
}
|
||||
} else {
|
||||
holder.delete.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
/*Friend[] friends = LinphoneManager.getLc().getFriendsLists();
|
||||
if (!ContactsManager.getInstance().isContactPresenceDisabled() && friends != null) {
|
||||
holder.friendStatus.setVisibility(View.VISIBLE);
|
||||
PresenceActivityType presenceActivity = friends[0].getPresenceModel().getActivity().getType();
|
||||
if (presenceActivity == PresenceActivityType.Online) {
|
||||
holder.friendStatus.setImageResource(R.drawable.led_connected);
|
||||
} else if (presenceActivity == PresenceActivityType.Busy) {
|
||||
holder.friendStatus.setImageResource(R.drawable.led_error);
|
||||
} else if (presenceActivity == PresenceActivityType.Away) {
|
||||
holder.friendStatus.setImageResource(R.drawable.led_inprogress);
|
||||
} else if (presenceActivity == PresenceActivityType.Offline) {
|
||||
holder.friendStatus.setImageResource(R.drawable.led_disconnected);
|
||||
} else {
|
||||
holder.friendStatus.setImageResource(R.drawable.call_quality_indicator_0);
|
||||
}
|
||||
}*/
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getSections() {
|
||||
return sections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionForSection(int sectionIndex) {
|
||||
if (sectionIndex >= sections.length || sectionIndex < 0) {
|
||||
return 0;
|
||||
}
|
||||
return map.get(sections[sectionIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSectionForPosition(int position) {
|
||||
if (position >= contacts.size() || position < 0) {
|
||||
return 0;
|
||||
}
|
||||
LinphoneContact contact = contacts.get(position);
|
||||
String fullName = contact.getFullName();
|
||||
if (fullName == null || fullName.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
String letter = fullName.substring(0, 1).toUpperCase(Locale.getDefault());
|
||||
return sectionsList.indexOf(letter);
|
||||
}
|
||||
ContactsManager.getInstance().deleteMultipleContactsAtOnce(ids);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
package org.linphone.contacts;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
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;
|
||||
|
||||
|
@ -40,30 +40,48 @@ import org.linphone.core.SearchResult;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchContactsListAdapter extends BaseAdapter {
|
||||
public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContactsListAdapter.ViewHolder> {
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = SearchContactsListAdapter.class.getSimpleName();
|
||||
|
||||
private class ViewHolder {
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
public TextView name;
|
||||
public TextView address;
|
||||
public ImageView linphoneContact;
|
||||
public ImageView isSelect;
|
||||
public ImageView avatar;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
private ClickListener listener;
|
||||
|
||||
public ViewHolder(View view, ClickListener listener) {
|
||||
super(view);
|
||||
name = view.findViewById(R.id.contact_name);
|
||||
address = view.findViewById(R.id.contact_address);
|
||||
linphoneContact = view.findViewById(R.id.contact_linphone);
|
||||
isSelect = view.findViewById(R.id.contact_is_select);
|
||||
avatar = view.findViewById(R.id.contact_picture);
|
||||
this.listener=listener;
|
||||
view.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (listener != null) {
|
||||
listener.onItemClicked(getAdapterPosition());
|
||||
}
|
||||
|
||||
}
|
||||
public interface ClickListener {
|
||||
void onItemClicked(int position);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<ContactAddress> contacts;
|
||||
private List<ContactAddress> contactsSelected;
|
||||
private LayoutInflater mInflater;
|
||||
private ProgressBar progressBar;
|
||||
private boolean mOnlySipContact = false;
|
||||
private View.OnClickListener listener;
|
||||
private ViewHolder.ClickListener listener;
|
||||
|
||||
public List<ContactAddress> getContacts() {
|
||||
return contacts;
|
||||
|
@ -73,17 +91,78 @@ public class SearchContactsListAdapter extends BaseAdapter {
|
|||
mOnlySipContact = enable;
|
||||
}
|
||||
|
||||
public void setListener(View.OnClickListener listener) {
|
||||
public void setListener(ViewHolder.ClickListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public SearchContactsListAdapter(List<ContactAddress> contactsList, LayoutInflater inflater, ProgressBar pB) {
|
||||
mInflater = inflater;
|
||||
public SearchContactsListAdapter(List<ContactAddress> contactsList, ProgressBar pB, ViewHolder.ClickListener clickListener) {
|
||||
this.listener=clickListener;
|
||||
progressBar = pB;
|
||||
setContactsSelectedList(null);
|
||||
setContactsList(contactsList);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_contact_cell, parent, false);
|
||||
return new ViewHolder(v, listener);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
ContactAddress contact = getItem(position);
|
||||
final String a = (contact.getAddressAsDisplayableString().isEmpty()) ? contact.getPhoneNumber() : contact.getAddressAsDisplayableString();
|
||||
LinphoneContact c = contact.getContact();
|
||||
|
||||
holder.avatar.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
if (c != null && c.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.avatar, c.getThumbnailUri());
|
||||
}
|
||||
|
||||
String address = contact.getAddressAsDisplayableString();
|
||||
if (c != null && c.getFullName() != null) {
|
||||
if (address == null)
|
||||
address = c.getPresenceModelForUriOrTel(a);
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText(c.getFullName());
|
||||
} else if (contact.getAddress() != null) {
|
||||
if (contact.getAddress().getUsername() != null) {
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText(contact.getAddress().getUsername());
|
||||
} else if (contact.getAddress().getDisplayName() != null) {
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText(contact.getAddress().getDisplayName());
|
||||
}
|
||||
} else if (address != null) {
|
||||
Address tmpAddr = Factory.instance().createAddress(address);
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText((tmpAddr.getDisplayName() != null) ? tmpAddr.getDisplayName() : tmpAddr.getUsername()) ;
|
||||
} else {
|
||||
holder.name.setVisibility(View.GONE);
|
||||
}
|
||||
holder.address.setText(a);
|
||||
if (holder.linphoneContact != null) {
|
||||
if (contact.isLinphoneContact() && c != null && c.isInFriendList() && address != null) {
|
||||
holder.linphoneContact.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.linphoneContact.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (holder.isSelect != null) {
|
||||
if (contactIsSelected(contact)) {
|
||||
holder.isSelect.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.isSelect.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
private boolean contactIsSelected(ContactAddress ca) {
|
||||
for (ContactAddress c : contactsSelected) {
|
||||
Address addr = c.getAddress();
|
||||
|
@ -160,11 +239,14 @@ public class SearchContactsListAdapter extends BaseAdapter {
|
|||
return contacts.get(position);
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return contacts.size();
|
||||
}
|
||||
|
||||
public void searchContacts(String search, ListView resultContactsSearch) {
|
||||
public void searchContacts(String search, RecyclerView resultContactsSearch) {
|
||||
List<ContactAddress> result = new ArrayList<>();
|
||||
|
||||
String domain = "";
|
||||
|
@ -205,70 +287,5 @@ public class SearchContactsListAdapter extends BaseAdapter {
|
|||
resultContactsSearch.setAdapter(this);
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view;
|
||||
ViewHolder holder;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ContactAddress contact = getItem(position);
|
||||
final String a = (contact.getAddressAsDisplayableString().isEmpty()) ? contact.getPhoneNumber() : contact.getAddressAsDisplayableString();
|
||||
LinphoneContact c = contact.getContact();
|
||||
|
||||
holder.avatar.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
if (c != null && c.hasPhoto()) {
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.avatar, c.getThumbnailUri());
|
||||
}
|
||||
|
||||
String address = contact.getAddressAsDisplayableString();
|
||||
if (c != null && c.getFullName() != null) {
|
||||
if (address == null)
|
||||
address = c.getPresenceModelForUriOrTel(a);
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText(c.getFullName());
|
||||
} else if (contact.getAddress() != null) {
|
||||
if (contact.getAddress().getUsername() != null) {
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText(contact.getAddress().getUsername());
|
||||
} else if (contact.getAddress().getDisplayName() != null) {
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText(contact.getAddress().getDisplayName());
|
||||
}
|
||||
} else if (address != null) {
|
||||
Address tmpAddr = Factory.instance().createAddress(address);
|
||||
holder.name.setVisibility(View.VISIBLE);
|
||||
holder.name.setText((tmpAddr.getDisplayName() != null) ? tmpAddr.getDisplayName() : tmpAddr.getUsername()) ;
|
||||
} else {
|
||||
holder.name.setVisibility(View.GONE);
|
||||
}
|
||||
holder.address.setText(a);
|
||||
if (holder.linphoneContact != null) {
|
||||
if (contact.isLinphoneContact() && c != null && c.isInFriendList() && address != null) {
|
||||
holder.linphoneContact.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.linphoneContact.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (holder.isSelect != null) {
|
||||
if (contactIsSelected(contact)) {
|
||||
holder.isSelect.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.isSelect.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
view.setTag(R.id.contact_search_name, address != null ? address : a);
|
||||
if (listener != null)
|
||||
view.setOnClickListener(listener);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,76 +19,68 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.contacts.ContactsManager;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.contacts.LinphoneContact;
|
||||
import org.linphone.LinphoneManager;
|
||||
import org.linphone.LinphoneUtils;
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.core.Call;
|
||||
import org.linphone.core.Address;
|
||||
import org.linphone.core.CallLog;
|
||||
import org.linphone.core.Call.Status;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class HistoryListFragment extends Fragment implements OnClickListener, OnItemClickListener, ContactsUpdatedListener {
|
||||
private ListView historyList;
|
||||
private LayoutInflater mInflater;
|
||||
import org.linphone.LinphoneManager;
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
import org.linphone.call.CallHistoryAdapter;
|
||||
import org.linphone.contacts.ContactsManager;
|
||||
import org.linphone.contacts.ContactsUpdatedListener;
|
||||
import org.linphone.core.Address;
|
||||
import org.linphone.core.Call;
|
||||
import org.linphone.core.CallLog;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class HistoryListFragment extends Fragment implements OnClickListener, OnItemClickListener, CallHistoryAdapter.ViewHolder.ClickListener ,ContactsUpdatedListener,SelectableHelper.DeleteListener{
|
||||
private RecyclerView historyList;
|
||||
private TextView noCallHistory, noMissedCallHistory;
|
||||
private ImageView missedCalls, allCalls, edit, selectAll, deselectAll, delete, cancel;
|
||||
private ImageView missedCalls, allCalls, edit;
|
||||
private View allCallsSelected, missedCallsSelected;
|
||||
private LinearLayout editList, topBar;
|
||||
private boolean onlyDisplayMissedCalls, isEditMode;
|
||||
private boolean mOnlyDisplayMissedCalls, mIsEditMode;
|
||||
private List<CallLog> mLogs;
|
||||
private CallHistoryAdapter mHistoryAdapter;
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
private Context mContext;
|
||||
private SelectableHelper mSelectionHelper;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
mInflater = inflater;
|
||||
View view = inflater.inflate(R.layout.history, container, false);
|
||||
mContext = getActivity().getApplicationContext();
|
||||
mSelectionHelper = new SelectableHelper(view, this);
|
||||
|
||||
noCallHistory = (TextView) view.findViewById(R.id.no_call_history);
|
||||
noMissedCallHistory = (TextView) view.findViewById(R.id.no_missed_call_history);
|
||||
|
||||
historyList = (ListView) view.findViewById(R.id.history_list);
|
||||
historyList.setOnItemClickListener(this);
|
||||
historyList = (RecyclerView) view.findViewById(R.id.history_list);
|
||||
|
||||
delete = (ImageView) view.findViewById(R.id.delete);
|
||||
delete.setOnClickListener(this);
|
||||
|
||||
editList = (LinearLayout) view.findViewById(R.id.edit_list);
|
||||
topBar = (LinearLayout) view.findViewById(R.id.top_bar);
|
||||
|
||||
cancel = (ImageView) view.findViewById(R.id.cancel);
|
||||
cancel.setOnClickListener(this);
|
||||
mLayoutManager = new LinearLayoutManager(mContext);
|
||||
historyList.setLayoutManager(mLayoutManager);
|
||||
//Divider between items
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(historyList.getContext(),
|
||||
mLayoutManager.getOrientation());
|
||||
dividerItemDecoration.setDrawable(mContext.getResources().getDrawable(R.drawable.divider));
|
||||
historyList.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
allCalls = (ImageView) view.findViewById(R.id.all_calls);
|
||||
allCalls.setOnClickListener(this);
|
||||
|
@ -100,17 +92,10 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
|||
|
||||
missedCallsSelected = view.findViewById(R.id.missed_calls_select);
|
||||
|
||||
selectAll = (ImageView) view.findViewById(R.id.select_all);
|
||||
selectAll.setOnClickListener(this);
|
||||
|
||||
deselectAll = (ImageView) view.findViewById(R.id.deselect_all);
|
||||
deselectAll.setOnClickListener(this);
|
||||
|
||||
allCalls.setEnabled(false);
|
||||
onlyDisplayMissedCalls = false;
|
||||
mOnlyDisplayMissedCalls = false;
|
||||
|
||||
edit = (ImageView) view.findViewById(R.id.edit);
|
||||
edit.setOnClickListener(this);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
@ -119,13 +104,6 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
|||
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
|
||||
}
|
||||
|
||||
private void selectAllList(boolean isSelectAll){
|
||||
int size = historyList.getAdapter().getCount();
|
||||
for(int i=0; i<size; i++) {
|
||||
historyList.setItemChecked(i,isSelectAll);
|
||||
}
|
||||
}
|
||||
|
||||
public void displayFirstLog(){
|
||||
if (mLogs != null && mLogs.size() > 0) {
|
||||
CallLog log = mLogs.get(0);
|
||||
|
@ -141,39 +119,8 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
|||
}
|
||||
}
|
||||
|
||||
private void removeCallLogs(){
|
||||
int size = historyList.getAdapter().getCount();
|
||||
for(int i=0; i<size; i++) {
|
||||
if(historyList.isItemChecked(i)){
|
||||
CallLog log = mLogs.get(i);
|
||||
LinphoneManager.getLc().removeCallLog(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getNbItemsChecked(){
|
||||
int size = historyList.getAdapter().getCount();
|
||||
int nb = 0;
|
||||
for(int i=0; i<size; i++) {
|
||||
if(historyList.isItemChecked(i)) {
|
||||
nb ++;
|
||||
}
|
||||
}
|
||||
return nb;
|
||||
}
|
||||
|
||||
public void enabledDeleteButton(Boolean enabled){
|
||||
if(enabled){
|
||||
delete.setEnabled(true);
|
||||
} else {
|
||||
if (getNbItemsChecked() == 0){
|
||||
delete.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeNotMissedCallsFromLogs() {
|
||||
if (onlyDisplayMissedCalls) {
|
||||
if (mOnlyDisplayMissedCalls) {
|
||||
List<CallLog> missedCalls = new ArrayList<CallLog>();
|
||||
for (CallLog log : mLogs) {
|
||||
if (log.getStatus() == Call.Status.Missed) {
|
||||
|
@ -187,7 +134,7 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
|||
private boolean hideHistoryListAndDisplayMessageIfEmpty() {
|
||||
removeNotMissedCallsFromLogs();
|
||||
if (mLogs.isEmpty()) {
|
||||
if (onlyDisplayMissedCalls) {
|
||||
if (mOnlyDisplayMissedCalls) {
|
||||
noMissedCallHistory.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
noCallHistory.setVisibility(View.VISIBLE);
|
||||
|
@ -217,8 +164,10 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
|||
|
||||
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
|
||||
if (!hideHistoryListAndDisplayMessageIfEmpty()) {
|
||||
historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
|
||||
mHistoryAdapter = new CallHistoryAdapter(getActivity().getApplicationContext(), mLogs, this, mSelectionHelper);
|
||||
historyList.setAdapter(mHistoryAdapter);
|
||||
mSelectionHelper.setAdapter(mHistoryAdapter);
|
||||
mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,62 +191,12 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
|||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
|
||||
if (id == R.id.select_all) {
|
||||
deselectAll.setVisibility(View.VISIBLE);
|
||||
selectAll.setVisibility(View.GONE);
|
||||
enabledDeleteButton(true);
|
||||
selectAllList(true);
|
||||
return;
|
||||
}
|
||||
if (id == R.id.deselect_all) {
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
enabledDeleteButton(false);
|
||||
selectAllList(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == R.id.cancel) {
|
||||
quitEditMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == R.id.delete) {
|
||||
if(historyList.getCheckedItemCount() == 0) {
|
||||
quitEditMode();
|
||||
return;
|
||||
}
|
||||
|
||||
final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.delete_text));
|
||||
Button delete = (Button) dialog.findViewById(R.id.delete_button);
|
||||
Button cancel = (Button) dialog.findViewById(R.id.cancel);
|
||||
|
||||
delete.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
removeCallLogs();
|
||||
dialog.dismiss();
|
||||
quitEditMode();
|
||||
}
|
||||
});
|
||||
|
||||
cancel.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dialog.dismiss();
|
||||
quitEditMode();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == R.id.all_calls) {
|
||||
allCalls.setEnabled(false);
|
||||
allCallsSelected.setVisibility(View.VISIBLE);
|
||||
missedCallsSelected.setVisibility(View.INVISIBLE);
|
||||
missedCalls.setEnabled(true);
|
||||
onlyDisplayMissedCalls = false;
|
||||
mOnlyDisplayMissedCalls = false;
|
||||
refresh();
|
||||
}
|
||||
if (id == R.id.missed_calls) {
|
||||
|
@ -305,251 +204,61 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
|||
allCallsSelected.setVisibility(View.INVISIBLE);
|
||||
missedCallsSelected.setVisibility(View.VISIBLE);
|
||||
missedCalls.setEnabled(false);
|
||||
onlyDisplayMissedCalls = true;
|
||||
mOnlyDisplayMissedCalls = true;
|
||||
}
|
||||
|
||||
if (id == R.id.edit) {
|
||||
topBar.setVisibility(View.GONE);
|
||||
editList.setVisibility(View.VISIBLE);
|
||||
enabledDeleteButton(false);
|
||||
isEditMode = true;
|
||||
}
|
||||
|
||||
if (!hideHistoryListAndDisplayMessageIfEmpty()) {
|
||||
historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
|
||||
}
|
||||
|
||||
if(isEditMode){
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
// historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
mHistoryAdapter = new CallHistoryAdapter(mContext, mLogs, this ,mSelectionHelper);
|
||||
historyList.setAdapter(mHistoryAdapter);
|
||||
mSelectionHelper.setAdapter(mHistoryAdapter);
|
||||
mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
|
||||
if (isEditMode) {
|
||||
if (mHistoryAdapter.isEditionEnabled()) {
|
||||
CallLog log = mLogs.get(position);
|
||||
LinphoneManager.getLc().removeCallLog(log);
|
||||
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
|
||||
}
|
||||
}
|
||||
|
||||
public void quitEditMode(){
|
||||
isEditMode = false;
|
||||
editList.setVisibility(View.GONE);
|
||||
topBar.setVisibility(View.VISIBLE);
|
||||
|
||||
refresh();
|
||||
if (!hideHistoryListAndDisplayMessageIfEmpty()) {
|
||||
historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
|
||||
}
|
||||
if (getResources().getBoolean(R.bool.isTablet)) {
|
||||
displayFirstLog();
|
||||
@Override
|
||||
public void onDeleteSelection(Object[] objectsToDelete) {
|
||||
int size = mHistoryAdapter.getSelectedItemCount();
|
||||
for(int i=0; i<size; i++) {
|
||||
CallLog log = (CallLog) objectsToDelete[i];
|
||||
LinphoneManager.getLc().removeCallLog(log);
|
||||
onResume();
|
||||
}
|
||||
}
|
||||
|
||||
class CallHistoryAdapter extends BaseAdapter {
|
||||
private class ViewHolder {
|
||||
public TextView contact;
|
||||
public ImageView detail;
|
||||
public CheckBox select;
|
||||
public ImageView callDirection;
|
||||
public ImageView contactPicture;
|
||||
public RelativeLayout CallContact;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
contact = (TextView) view.findViewById(R.id.sip_uri);
|
||||
detail = (ImageView) view.findViewById(R.id.detail);
|
||||
select = (CheckBox) view.findViewById(R.id.delete);
|
||||
callDirection = (ImageView) view.findViewById(R.id.icon);
|
||||
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
|
||||
CallContact = (RelativeLayout) view.findViewById(R.id.history_click);
|
||||
}
|
||||
}
|
||||
|
||||
CallHistoryAdapter(Context aContext) {
|
||||
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mLogs.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return mLogs.get(position);
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
private String timestampToHumanDate(Calendar cal) {
|
||||
SimpleDateFormat dateFormat;
|
||||
if (isToday(cal)) {
|
||||
return getString(R.string.today);
|
||||
} else if (isYesterday(cal)) {
|
||||
return getString(R.string.yesterday);
|
||||
} else {
|
||||
dateFormat = new SimpleDateFormat(getResources().getString(R.string.history_date_format));
|
||||
}
|
||||
|
||||
return dateFormat.format(cal.getTime());
|
||||
}
|
||||
|
||||
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 boolean isToday(Calendar cal) {
|
||||
return isSameDay(cal, Calendar.getInstance());
|
||||
}
|
||||
|
||||
private boolean isYesterday(Calendar cal) {
|
||||
Calendar yesterday = Calendar.getInstance();
|
||||
yesterday.roll(Calendar.DAY_OF_MONTH, -1);
|
||||
return isSameDay(cal, yesterday);
|
||||
}
|
||||
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
View view = null;
|
||||
ViewHolder holder = null;
|
||||
|
||||
if (convertView != null) {
|
||||
view = convertView;
|
||||
holder = (ViewHolder) view.getTag();
|
||||
} else {
|
||||
view = mInflater.inflate(R.layout.history_cell, parent,false);
|
||||
holder = new ViewHolder(view);
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
if (mLogs == null || mLogs.size() < position) return view;
|
||||
|
||||
final CallLog log = mLogs.get(position);
|
||||
long timestamp = log.getStartDate() * 1000;
|
||||
Address address;
|
||||
|
||||
holder.contact.setSelected(true); // For automated horizontal scrolling of long texts
|
||||
|
||||
LinearLayout separator = (LinearLayout) view.findViewById(R.id.separator);
|
||||
TextView separatorText = (TextView) view.findViewById(R.id.separator_text);
|
||||
Calendar logTime = Calendar.getInstance();
|
||||
logTime.setTimeInMillis(timestamp);
|
||||
separatorText.setText(timestampToHumanDate(logTime));
|
||||
|
||||
if (position > 0) {
|
||||
CallLog previousLog = mLogs.get(position-1);
|
||||
long previousTimestamp = previousLog.getStartDate() * 1000;
|
||||
Calendar previousLogTime = Calendar.getInstance();
|
||||
previousLogTime.setTimeInMillis(previousTimestamp);
|
||||
|
||||
if (isSameDay(previousLogTime, logTime)) {
|
||||
separator.setVisibility(View.GONE);
|
||||
@Override
|
||||
public void onItemClicked(int position) {
|
||||
if (mHistoryAdapter.isEditionEnabled()) {
|
||||
mHistoryAdapter.toggleSelection(position);
|
||||
} else {
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
CallLog log = mLogs.get(position);
|
||||
Address address;
|
||||
if (log.getDir() == Call.Dir.Incoming) {
|
||||
address = log.getFromAddress();
|
||||
} else {
|
||||
separator.setVisibility(View.VISIBLE);
|
||||
address = log.getToAddress();
|
||||
}
|
||||
} else {
|
||||
separator.setVisibility(View.VISIBLE);
|
||||
LinphoneActivity.instance().setAddresGoToDialerAndCall(address.asStringUriOnly(), address.getDisplayName(), null);
|
||||
}
|
||||
|
||||
if (log.getDir() == Call.Dir.Incoming) {
|
||||
address = log.getFromAddress();
|
||||
if (log.getStatus() == Call.Status.Missed) {
|
||||
holder.callDirection.setImageResource(R.drawable.call_status_missed);
|
||||
} else {
|
||||
holder.callDirection.setImageResource(R.drawable.call_status_incoming);
|
||||
}
|
||||
} else {
|
||||
address = log.getToAddress();
|
||||
holder.callDirection.setImageResource(R.drawable.call_status_outgoing);
|
||||
}
|
||||
|
||||
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
|
||||
String displayName = null;
|
||||
final String sipUri = (address != null) ? address.asString() : "";
|
||||
if (c != null) {
|
||||
displayName = c.getFullName();
|
||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), holder.contactPicture, c.getThumbnailUri());
|
||||
} else {
|
||||
holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
|
||||
}
|
||||
|
||||
if (displayName == null) {
|
||||
holder.contact.setText(LinphoneUtils.getAddressDisplayName(sipUri));
|
||||
} else {
|
||||
holder.contact.setText(displayName);
|
||||
}
|
||||
|
||||
if (isEditMode) {
|
||||
holder.CallContact.setOnClickListener(null);
|
||||
holder.select.setVisibility(View.VISIBLE);
|
||||
holder.select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
historyList.setItemChecked(position, b);
|
||||
if(getNbItemsChecked() == getCount()){
|
||||
deselectAll.setVisibility(View.VISIBLE);
|
||||
selectAll.setVisibility(View.GONE);
|
||||
enabledDeleteButton(true);
|
||||
} else {
|
||||
if(getNbItemsChecked() == 0){
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
enabledDeleteButton(false);
|
||||
} else {
|
||||
deselectAll.setVisibility(View.GONE);
|
||||
selectAll.setVisibility(View.VISIBLE);
|
||||
enabledDeleteButton(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
holder.detail.setVisibility(View.INVISIBLE);
|
||||
if(historyList.isItemChecked(position)) {
|
||||
holder.select.setChecked(true);
|
||||
} else {
|
||||
holder.select.setChecked(false);
|
||||
}
|
||||
} else {
|
||||
holder.select.setVisibility(View.GONE);
|
||||
holder.detail.setVisibility(View.VISIBLE);
|
||||
holder.detail.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().displayHistoryDetail(sipUri, log);
|
||||
}
|
||||
}
|
||||
});
|
||||
holder.CallContact.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
CallLog log = mLogs.get(position);
|
||||
Address address;
|
||||
if (log.getDir() == Call.Dir.Incoming) {
|
||||
address = log.getFromAddress();
|
||||
} else {
|
||||
address = log.getToAddress();
|
||||
}
|
||||
if (address != null) {
|
||||
LinphoneActivity.instance().setAddresGoToDialerAndCall(address.asStringUriOnly(), address.getDisplayName(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClicked(int position) {
|
||||
if (!mHistoryAdapter.isEditionEnabled()) {
|
||||
mSelectionHelper.enterEditionMode();
|
||||
}
|
||||
mHistoryAdapter.toggleSelection(position);
|
||||
return true;
|
||||
}
|
||||
}
|
111
src/android/org/linphone/ui/SelectableAdapter.java
Normal file
111
src/android/org/linphone/ui/SelectableAdapter.java
Normal file
|
@ -0,0 +1,111 @@
|
|||
package org.linphone.ui;
|
||||
|
||||
/*
|
||||
SelectableAdapter.java
|
||||
Copyright (C) 2018 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.support.v7.widget.RecyclerView;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = SelectableAdapter.class.getSimpleName();
|
||||
private SparseBooleanArray mSelectedItems;
|
||||
private boolean mIsEditionEnabled=false;
|
||||
private SelectableHelper mListHelper;
|
||||
|
||||
public SelectableAdapter(SelectableHelper helper) {
|
||||
mSelectedItems = new SparseBooleanArray();
|
||||
mListHelper = helper;
|
||||
}
|
||||
|
||||
public boolean isEditionEnabled() {
|
||||
return mIsEditionEnabled;
|
||||
}
|
||||
|
||||
public void enableEdition(boolean set) {
|
||||
mIsEditionEnabled = set;
|
||||
|
||||
mSelectedItems.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
/**
|
||||
* 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 (mSelectedItems.get(position, false)) {
|
||||
mSelectedItems.delete(position);
|
||||
} else {
|
||||
mSelectedItems.put(position, true);
|
||||
}
|
||||
mListHelper.updateSelectionButtons(getSelectedItemCount() == 0, getSelectedItemCount() == getItemCount());
|
||||
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the selected items
|
||||
* @return Selected items count
|
||||
*/
|
||||
public int getSelectedItemCount() {
|
||||
return mSelectedItems.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the list of selected items
|
||||
* @return List of selected items ids
|
||||
*/
|
||||
public List<Integer> getSelectedItems() {
|
||||
List<Integer> items = new ArrayList<>(mSelectedItems.size());
|
||||
for (int i = 0; i < mSelectedItems.size(); ++i) {
|
||||
items.add(mSelectedItems.keyAt(i));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
for (Integer i = 0; i < getItemCount(); i++) {
|
||||
mSelectedItems.put(i, true);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
mListHelper.updateSelectionButtons(false, true);
|
||||
}
|
||||
|
||||
public void deselectAll() {
|
||||
mSelectedItems.clear();
|
||||
mListHelper.updateSelectionButtons(true, false);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
public abstract Object getItem(int position);
|
||||
}
|
179
src/android/org/linphone/ui/SelectableHelper.java
Normal file
179
src/android/org/linphone/ui/SelectableHelper.java
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
SelectableHelper.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.ui;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
|
||||
public class SelectableHelper {
|
||||
private ImageView mEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton, mCancelButton;
|
||||
private LinearLayout mEditTopBar, mTopBar;
|
||||
private SelectableAdapter<RecyclerView.ViewHolder> mAdapter;
|
||||
private DeleteListener mDeleteListener;
|
||||
private Context mContext;
|
||||
private int mDialogDeleteMessageResourceId;
|
||||
|
||||
public void setDialogMessage(int id) {
|
||||
mDialogDeleteMessageResourceId = id;
|
||||
}
|
||||
|
||||
public interface DeleteListener {
|
||||
void onDeleteSelection(Object[] objectsToDelete);
|
||||
}
|
||||
|
||||
public SelectableHelper(View view, DeleteListener listener) {
|
||||
mContext = view.getContext();
|
||||
mDeleteListener = listener;
|
||||
|
||||
//Define XML layout items used for selection mode
|
||||
|
||||
mEditTopBar = view.findViewById(R.id.edit_list);
|
||||
mTopBar = view.findViewById(R.id.top_bar);
|
||||
|
||||
mCancelButton = view.findViewById(R.id.cancel);
|
||||
mCancelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
quitEditionMode();
|
||||
}
|
||||
});
|
||||
|
||||
mEditButton = view.findViewById(R.id.edit);
|
||||
|
||||
//Set visibility behaviour on click on edit button + enter Edition Mode
|
||||
mEditButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mAdapter.getItemCount() > 0) {
|
||||
enterEditionMode();
|
||||
mTopBar.setVisibility(View.GONE);
|
||||
mEditTopBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mSelectAllButton = view.findViewById(R.id.select_all);
|
||||
mSelectAllButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mAdapter.selectAll();
|
||||
}
|
||||
});
|
||||
|
||||
mDeselectAllButton = view.findViewById(R.id.deselect_all);
|
||||
mDeselectAllButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mAdapter.deselectAll();
|
||||
}
|
||||
});
|
||||
|
||||
mDeleteSelectionButton = view.findViewById(R.id.delete);
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
|
||||
//Display confirmation for deletion
|
||||
mDeleteSelectionButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final Dialog dialog = LinphoneActivity.instance().displayDialog(mContext.getString(mDialogDeleteMessageResourceId));
|
||||
Button delete = dialog.findViewById(R.id.delete_button);
|
||||
Button cancel = dialog.findViewById(R.id.cancel);
|
||||
|
||||
delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mDeleteListener.onDeleteSelection(getSelectedObjects());
|
||||
dialog.dismiss();
|
||||
quitEditionMode();
|
||||
}
|
||||
});
|
||||
|
||||
cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dialog.dismiss();
|
||||
quitEditionMode();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
});
|
||||
|
||||
mDialogDeleteMessageResourceId = R.string.delete_text;
|
||||
}
|
||||
|
||||
public void setAdapter(SelectableAdapter adapter) {
|
||||
mAdapter=adapter;
|
||||
}
|
||||
|
||||
public void updateSelectionButtons(boolean isSelectionEmpty, boolean isSelectionFull) {
|
||||
//Delete button availability
|
||||
if (isSelectionEmpty) {
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
} else {
|
||||
mDeleteSelectionButton.setEnabled(true);
|
||||
}
|
||||
|
||||
//(De)select button visibility
|
||||
if (isSelectionFull) {
|
||||
mSelectAllButton.setVisibility(View.GONE);
|
||||
mDeselectAllButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mSelectAllButton.setVisibility(View.VISIBLE);
|
||||
mDeselectAllButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void quitEditionMode() {
|
||||
mAdapter.enableEdition(false);
|
||||
mTopBar.setVisibility(View.VISIBLE);
|
||||
mEditTopBar.setVisibility(View.GONE);
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
mSelectAllButton.setVisibility(View.GONE);
|
||||
mDeselectAllButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void enterEditionMode() {
|
||||
mAdapter.enableEdition(true);
|
||||
mTopBar.setVisibility(View.GONE);
|
||||
mEditTopBar.setVisibility(View.VISIBLE);
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
mSelectAllButton.setVisibility(View.VISIBLE);
|
||||
mDeselectAllButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private Object[] getSelectedObjects() {
|
||||
Object objects[] = new Object[mAdapter.getSelectedItemCount()];
|
||||
int index = 0;
|
||||
for (Integer i : mAdapter.getSelectedItems()) {
|
||||
objects[index] = mAdapter.getItem(i);
|
||||
index++;
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue