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/libvpx/x86
|
||||||
submodules/externals/build/openh264/arm
|
submodules/externals/build/openh264/arm
|
||||||
submodules/externals/build/openh264/x86
|
submodules/externals/build/openh264/x86
|
||||||
|
submodules/externals/ffmpeg/arm/
|
||||||
tests/*$py.class
|
tests/*$py.class
|
||||||
tests/build.xml
|
tests/build.xml
|
||||||
tests/project.properties
|
tests/project.properties
|
||||||
|
|
|
@ -64,7 +64,9 @@
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:largeHeap="true">
|
android:largeHeap="true"
|
||||||
|
>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.LinphoneLauncherActivity"
|
android:name=".activities.LinphoneLauncherActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|
|
@ -47,7 +47,10 @@ dependencies {
|
||||||
if (firebaseEnable()) {
|
if (firebaseEnable()) {
|
||||||
implementation 'com.google.firebase:firebase-messaging:15.0.2'
|
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')
|
implementation project(':liblinphone-sdk')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class LogsActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
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);
|
getMenuInflater().inflate(R.menu.activity_logs, menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class MainActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
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);
|
getMenuInflater().inflate(R.menu.activity_main, menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class SuitesActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
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);
|
getMenuInflater().inflate(R.menu.activity_suites, menu);
|
||||||
return true;
|
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_height="wrap_content"
|
||||||
android:layout_above="@id/footer"/>
|
android:layout_above="@id/footer"/>
|
||||||
|
|
||||||
<ListView
|
<android.support.v7.widget.RecyclerView
|
||||||
|
|
||||||
android:id="@+id/chat_message_list"
|
android:id="@+id/chat_message_list"
|
||||||
android:divider="@android:color/transparent"
|
android:divider="@android:color/transparent"
|
||||||
android:choiceMode="multipleChoice"
|
android:choiceMode="multipleChoice"
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
android:layout_width="30dp"
|
android:layout_width="30dp"
|
||||||
android:layout_height="30dp"
|
android:layout_height="30dp"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
|
android:clickable="false"
|
||||||
android:layout_alignParentRight="true"/>
|
android:layout_alignParentRight="true"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -144,7 +144,7 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/relativeLayout">
|
android:id="@+id/relativeLayout">
|
||||||
|
|
||||||
<ListView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/contactsList"
|
android:id="@+id/contactsList"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<ListView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/chat_room_participants"
|
android:id="@+id/chat_room_participants"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
android:divider="@color/colorE"
|
android:divider="@color/colorE"
|
||||||
android:dividerHeight="1dp">
|
android:dividerHeight="1dp">
|
||||||
|
|
||||||
</ListView>
|
</android.support.v7.widget.RecyclerView>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/leaveGroupLayout"
|
android:id="@+id/leaveGroupLayout"
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
|
|
||||||
<include layout="@layout/edit_list"/>
|
<include layout="@layout/edit_list"/>
|
||||||
|
|
||||||
<ListView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/chatList"
|
android:id="@+id/chatList"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
android:paddingLeft="10dp"
|
android:paddingLeft="10dp"
|
||||||
android:paddingRight="10dp"
|
android:paddingRight="10dp"
|
||||||
android:paddingTop="5dp"
|
android:paddingTop="5dp"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
android:background="@drawable/list_selector">
|
android:background="@drawable/list_selector">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
android:contentDescription="@string/content_description_delete"
|
android:contentDescription="@string/content_description_delete"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="false"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
|
@ -121,5 +123,11 @@
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</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>
|
</RelativeLayout>
|
|
@ -69,6 +69,7 @@
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
android:clickable="false"
|
||||||
android:paddingLeft="5dp"
|
android:paddingLeft="5dp"
|
||||||
android:paddingRight="5dp" />
|
android:paddingRight="5dp" />
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:background="@color/colorH"
|
android:background="@color/colorH"
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/top_bar"
|
android:id="@+id/top_bar"
|
||||||
|
@ -119,13 +120,18 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<ListView
|
<!--android:fastScrollAlwaysVisible="true"-->
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/contactsList"
|
android:id="@+id/contactsList"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:divider="@color/colorE"
|
android:divider="@color/colorE"
|
||||||
android:fastScrollEnabled="true"
|
app:fastScrollEnabled="true"
|
||||||
android:fastScrollAlwaysVisible="true"
|
app:fastScrollHorizontalThumbDrawable="@drawable/fast_scroll"
|
||||||
|
app:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
|
||||||
|
app:fastScrollVerticalThumbDrawable="@drawable/fast_scroll"
|
||||||
|
app:fastScrollVerticalTrackDrawable="@drawable/line_drawable"
|
||||||
|
|
||||||
android:dividerHeight="1dp" />
|
android:dividerHeight="1dp" />
|
||||||
|
|
||||||
<ProgressBar
|
<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"/>
|
<include layout="@layout/edit_list"/>
|
||||||
|
|
||||||
<ListView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/history_list"
|
android:id="@+id/history_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
android:id="@+id/history_whole"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
android:layout_margin="5dp"
|
android:layout_margin="5dp"
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
android:clickable="false"
|
||||||
android:padding="5dp" />
|
android:padding="5dp" />
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
|
|
@ -6,12 +6,16 @@
|
||||||
<item name="android:fastScrollTextColor">@android:color/white</item>
|
<item name="android:fastScrollTextColor">@android:color/white</item>
|
||||||
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</item>
|
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style name="NoTitle" parent="android:Theme.Holo.Light.NoActionBar">
|
<style name="NoTitle" parent="android:Theme.Holo.Light.NoActionBar">
|
||||||
<item name="android:fastScrollThumbDrawable">@drawable/fast_scroll</item>
|
<item name="android:fastScrollThumbDrawable">@drawable/fast_scroll</item>
|
||||||
<item name="android:fastScrollTextColor">@android:color/white</item>
|
<item name="android:fastScrollTextColor">@android:color/white</item>
|
||||||
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</item>
|
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</item>
|
||||||
|
|
||||||
</style>
|
</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:fastScrollThumbDrawable">@drawable/fast_scroll</item>
|
||||||
<item name="android:fastScrollTextColor">@android:color/white</item>
|
<item name="android:fastScrollTextColor">@android:color/white</item>
|
||||||
<item name="android:fastScrollPreviewBackgroundRight">@drawable/fast_scroll_preview</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() {
|
menu.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
|
||||||
if(sideMenu.isDrawerVisible(Gravity.LEFT)){
|
if(sideMenu.isDrawerVisible(Gravity.LEFT)){
|
||||||
sideMenu.closeDrawer(sideMenuContent);
|
sideMenu.closeDrawer(sideMenuContent);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -152,8 +152,8 @@ public class CodecDownloaderFragment extends Fragment {
|
||||||
if (savedInstanceState.containsKey("downloaded"))
|
if (savedInstanceState.containsKey("downloaded"))
|
||||||
downloaded.setVisibility((Integer) savedInstanceState.getSerializable("downloaded"));
|
downloaded.setVisibility((Integer) savedInstanceState.getSerializable("downloaded"));
|
||||||
|
|
||||||
if (savedInstanceState.containsKey("bar"))
|
if (savedInstanceState.containsKey("context_bar"))
|
||||||
bar.setVisibility((Integer) savedInstanceState.getSerializable("bar"));
|
bar.setVisibility((Integer) savedInstanceState.getSerializable("context_bar"));
|
||||||
|
|
||||||
if (savedInstanceState.containsKey("downloadingInfo"))
|
if (savedInstanceState.containsKey("downloadingInfo"))
|
||||||
downloadingInfo.setVisibility((Integer) savedInstanceState.getSerializable("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 (yes != null) outState.putSerializable("yes", yes.getVisibility());
|
||||||
if (no != null) outState.putSerializable("no", no.getVisibility());
|
if (no != null) outState.putSerializable("no", no.getVisibility());
|
||||||
if (ok != null) outState.putSerializable("ok", ok.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());
|
if (downloadingInfo != null) outState.putSerializable("downloadingInfo", downloadingInfo.getVisibility());
|
||||||
super.onSaveInstanceState(outState);
|
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;
|
package org.linphone.chat;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
@ -29,12 +31,13 @@ import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.linphone.R;
|
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 String messageId;
|
||||||
|
public Context mContext;
|
||||||
|
public ChatMessage message;
|
||||||
public LinearLayout eventLayout;
|
public LinearLayout eventLayout;
|
||||||
//public TextView eventTime;
|
|
||||||
public TextView eventMessage;
|
public TextView eventMessage;
|
||||||
|
|
||||||
public RelativeLayout bubbleLayout;
|
public RelativeLayout bubbleLayout;
|
||||||
|
@ -61,35 +64,84 @@ public class ChatBubbleViewHolder {
|
||||||
public Button openFileButton;
|
public Button openFileButton;
|
||||||
|
|
||||||
public CheckBox delete;
|
public CheckBox delete;
|
||||||
|
private ClickListener listener;
|
||||||
|
|
||||||
public ChatBubbleViewHolder(View view) {
|
public ChatBubbleViewHolder(Context context, View view, ClickListener listener) {
|
||||||
eventLayout = view.findViewById(R.id.event);
|
super(view);
|
||||||
|
this.mContext = context;
|
||||||
|
|
||||||
|
this.eventLayout = view.findViewById(R.id.event);
|
||||||
//eventTime = view.findViewById(R.id.event_date);
|
//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);
|
this.bubbleLayout = view.findViewById(R.id.bubble);
|
||||||
separatorLayout = view.findViewById(R.id.separator);
|
this.background = view.findViewById(R.id.background);
|
||||||
background = view.findViewById(R.id.background);
|
this.contactPicture = view.findViewById(R.id.contact_picture);
|
||||||
contactPicture = view.findViewById(R.id.contact_picture);
|
this.contactPictureMask = view.findViewById(R.id.mask);
|
||||||
contactPictureMask = view.findViewById(R.id.mask);
|
this.contactName = view.findViewById(R.id.contact_header);
|
||||||
contactName = view.findViewById(R.id.contact_header);
|
|
||||||
|
|
||||||
messageStatus = view.findViewById(R.id.status);
|
this.messageStatus = view.findViewById(R.id.status);
|
||||||
messageSendingInProgress = view.findViewById(R.id.inprogress);
|
this.messageSendingInProgress = view.findViewById(R.id.inprogress);
|
||||||
imdmLayout = view.findViewById(R.id.imdmLayout);
|
this.imdmLayout = view.findViewById(R.id.imdmLayout);
|
||||||
imdmIcon = view.findViewById(R.id.imdmIcon);
|
this.imdmIcon = view.findViewById(R.id.imdmIcon);
|
||||||
imdmLabel = view.findViewById(R.id.imdmText);
|
this.imdmLabel = view.findViewById(R.id.imdmText);
|
||||||
|
|
||||||
messageText = view.findViewById(R.id.message);
|
this.messageText = view.findViewById(R.id.message);
|
||||||
messageImage = view.findViewById(R.id.image);
|
this.messageImage = view.findViewById(R.id.image);
|
||||||
|
this.separatorLayout = view.findViewById(R.id.separator);
|
||||||
|
|
||||||
fileTransferLayout = view.findViewById(R.id.file_transfer_layout);
|
this.fileTransferLayout = view.findViewById(R.id.file_transfer_layout);
|
||||||
fileTransferProgressBar = view.findViewById(R.id.progress_bar);
|
this.fileTransferProgressBar = view.findViewById(R.id.progress_bar);
|
||||||
fileTransferAction = view.findViewById(R.id.file_transfer_action);
|
this.fileTransferAction = view.findViewById(R.id.file_transfer_action);
|
||||||
|
|
||||||
fileName = view.findViewById(R.id.file_name);
|
this.fileName = view.findViewById(R.id.file_name);
|
||||||
openFileButton = view.findViewById(R.id.open_file);
|
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.app.Fragment;
|
||||||
import android.os.Bundle;
|
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.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.HorizontalScrollView;
|
import android.widget.HorizontalScrollView;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager;
|
import org.linphone.LinphoneManager;
|
||||||
import org.linphone.LinphonePreferences;
|
import org.linphone.LinphonePreferences;
|
||||||
|
import org.linphone.R;
|
||||||
|
import org.linphone.activities.LinphoneActivity;
|
||||||
import org.linphone.contacts.ContactAddress;
|
import org.linphone.contacts.ContactAddress;
|
||||||
import org.linphone.contacts.ContactsManager;
|
import org.linphone.contacts.ContactsManager;
|
||||||
import org.linphone.contacts.LinphoneNumberOrAddress;
|
import org.linphone.contacts.ContactsUpdatedListener;
|
||||||
import org.linphone.contacts.SearchContactsListAdapter;
|
import org.linphone.contacts.SearchContactsListAdapter;
|
||||||
import org.linphone.core.Address;
|
import org.linphone.core.Address;
|
||||||
import org.linphone.core.ChatRoom;
|
import org.linphone.core.ChatRoom;
|
||||||
import org.linphone.core.ChatRoomListenerStub;
|
import org.linphone.core.ChatRoomListenerStub;
|
||||||
import org.linphone.core.Core;
|
import org.linphone.core.Core;
|
||||||
import org.linphone.core.Factory;
|
|
||||||
import org.linphone.core.ProxyConfig;
|
import org.linphone.core.ProxyConfig;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
import org.linphone.ui.ContactSelectView;
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||||
|
|
||||||
public class ChatCreationFragment extends Fragment implements View.OnClickListener, AdapterView.OnItemClickListener, ContactsUpdatedListener {
|
public class ChatCreationFragment extends Fragment implements View.OnClickListener ,SearchContactsListAdapter.ViewHolder.ClickListener, ContactsUpdatedListener {
|
||||||
private LayoutInflater mInflater;
|
private RecyclerView mContactsList;
|
||||||
private ListView mContactsList;
|
|
||||||
private LinearLayout mContactsSelectedLayout;
|
private LinearLayout mContactsSelectedLayout;
|
||||||
private HorizontalScrollView mContactsSelectLayout;
|
private HorizontalScrollView mContactsSelectLayout;
|
||||||
private ArrayList<ContactAddress> mContactsSelected;
|
private ArrayList<ContactAddress> mContactsSelected;
|
||||||
|
@ -80,7 +78,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
mInflater = inflater;
|
super.onCreate(savedInstanceState);
|
||||||
View view = inflater.inflate(R.layout.chat_create, container, false);
|
View view = inflater.inflate(R.layout.chat_create, container, false);
|
||||||
|
|
||||||
mContactsSelected = new ArrayList<>();
|
mContactsSelected = new ArrayList<>();
|
||||||
|
@ -124,7 +122,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
||||||
mContactsFetchInProgress = view.findViewById(R.id.contactsFetchInProgress);
|
mContactsFetchInProgress = view.findViewById(R.id.contactsFetchInProgress);
|
||||||
mContactsFetchInProgress.setVisibility(View.VISIBLE);
|
mContactsFetchInProgress.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
mSearchAdapter = new SearchContactsListAdapter(null, mInflater, mContactsFetchInProgress);
|
mSearchAdapter = new SearchContactsListAdapter(null, mContactsFetchInProgress, this);
|
||||||
|
|
||||||
mSearchField = view.findViewById(R.id.searchField);
|
mSearchField = view.findViewById(R.id.searchField);
|
||||||
mSearchField.addTextChangedListener(new TextWatcher() {
|
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.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) {
|
if (savedInstanceState != null && savedInstanceState.getStringArrayList("mContactsSelected") != null) {
|
||||||
mContactsSelectedLayout.removeAllViews();
|
mContactsSelectedLayout.removeAllViews();
|
||||||
// We need to get all contacts not only sip
|
// 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) {
|
private void removeContactFromSelection(ContactAddress ca) {
|
||||||
updateContactsClick(ca, mSearchAdapter.getContactsSelectedList());
|
updateContactsClick(ca, mSearchAdapter.getContactsSelectedList());
|
||||||
mSearchAdapter.notifyDataSetInvalidated();
|
mSearchAdapter.notifyDataSetChanged();
|
||||||
updateListSelected();
|
updateListSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,6 +361,8 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Removed all selection mode related code, as it is now located into SelectableHelper.
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
int id = view.getId();
|
int id = view.getId();
|
||||||
|
@ -412,8 +427,8 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
public void onItemClicked(int position) {
|
||||||
ContactAddress ca = mSearchAdapter.getContacts().get(i);
|
ContactAddress ca = mSearchAdapter.getContacts().get(position);
|
||||||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
ProxyConfig lpc = lc.getDefaultProxyConfig();
|
ProxyConfig lpc = lc.getDefaultProxyConfig();
|
||||||
if (lpc == null || lpc.getConferenceFactoryUri() == null) {
|
if (lpc == null || lpc.getConferenceFactoryUri() == null) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.content.FileProvider;
|
import android.support.v4.content.FileProvider;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
|
@ -56,12 +57,11 @@ import org.linphone.core.Address;
|
||||||
import org.linphone.core.ChatMessage;
|
import org.linphone.core.ChatMessage;
|
||||||
import org.linphone.core.ChatMessageListenerStub;
|
import org.linphone.core.ChatMessageListenerStub;
|
||||||
import org.linphone.core.Content;
|
import org.linphone.core.Content;
|
||||||
import org.linphone.core.Event;
|
|
||||||
import org.linphone.core.EventLog;
|
import org.linphone.core.EventLog;
|
||||||
import org.linphone.core.LimeState;
|
import org.linphone.core.LimeState;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
import org.linphone.ui.ListSelectionAdapter;
|
import org.linphone.ui.SelectableAdapter;
|
||||||
import org.linphone.ui.ListSelectionHelper;
|
import org.linphone.ui.SelectableHelper;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -73,26 +73,29 @@ import java.util.List;
|
||||||
|
|
||||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
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 MARGIN_BETWEEN_MESSAGES = 10;
|
||||||
private static int SIDE_MARGIN = 100;
|
private static int SIDE_MARGIN = 100;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private List<EventLog> mHistory;
|
private List<EventLog> mHistory;
|
||||||
private List<LinphoneContact> mParticipants;
|
private List<LinphoneContact> mParticipants;
|
||||||
private LayoutInflater mLayoutInflater;
|
private int mItemResource;
|
||||||
private Bitmap mDefaultBitmap;
|
private Bitmap mDefaultBitmap;
|
||||||
private GroupChatFragment mFragment;
|
private GroupChatFragment mFragment;
|
||||||
private ChatMessageListenerStub mListener;
|
private ChatMessageListenerStub mListener;
|
||||||
|
|
||||||
public ChatEventsAdapter(GroupChatFragment fragment, ListSelectionHelper helper, LayoutInflater inflater, EventLog[] history, ArrayList<LinphoneContact> participants) {
|
private ChatBubbleViewHolder.ClickListener mClickListener;
|
||||||
|
|
||||||
|
public ChatEventsAdapter(GroupChatFragment fragment, SelectableHelper helper, int itemResource, EventLog[] history, ArrayList<LinphoneContact> participants, ChatBubbleViewHolder.ClickListener clickListener) {
|
||||||
super(helper);
|
super(helper);
|
||||||
mFragment = fragment;
|
mFragment = fragment;
|
||||||
mContext = mFragment.getActivity();
|
mContext = mFragment.getActivity();
|
||||||
mLayoutInflater = inflater;
|
mItemResource = itemResource;
|
||||||
mHistory = new ArrayList<>(Arrays.asList(history));
|
mHistory = new ArrayList<>(Arrays.asList(history));
|
||||||
mParticipants = participants;
|
mParticipants = participants;
|
||||||
|
mClickListener = clickListener;
|
||||||
mListener = new ChatMessageListenerStub() {
|
mListener = new ChatMessageListenerStub() {
|
||||||
@Override
|
@Override
|
||||||
public void onFileTransferProgressIndication(ChatMessage message, Content content, int offset, int total) {
|
public void onFileTransferProgressIndication(ChatMessage message, Content content, int offset, int total) {
|
||||||
|
@ -124,64 +127,23 @@ public class ChatEventsAdapter extends ListSelectionAdapter {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToHistory(EventLog log) {
|
@Override
|
||||||
mHistory.add(log);
|
public ChatBubbleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
notifyDataSetChanged();
|
View v = LayoutInflater.from(parent.getContext())
|
||||||
}
|
.inflate(this.mItemResource, parent, false);
|
||||||
|
ChatBubbleViewHolder VH = new ChatBubbleViewHolder(this.mContext,v, mClickListener);
|
||||||
|
|
||||||
public void setContacts(ArrayList<LinphoneContact> participants) {
|
//Allows onLongClick ContextMenu on bubbles
|
||||||
mParticipants = participants;
|
mFragment.registerForContextMenu(v);
|
||||||
}
|
v.setTag(VH);
|
||||||
|
return VH;
|
||||||
public void refresh(EventLog[] history) {
|
|
||||||
mHistory = new ArrayList<>(Arrays.asList(history));
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
for (EventLog event : mHistory) {
|
|
||||||
if (event.getType() == EventLog.Type.ConferenceChatMessage) {
|
|
||||||
ChatMessage message = event.getChatMessage();
|
|
||||||
message.setListener(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mHistory.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public void onBindViewHolder(@NonNull ChatBubbleViewHolder holder, int position) {
|
||||||
return mHistory.size();
|
final EventLog event = this.mHistory.get(position);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getItem(int i) {
|
|
||||||
return mHistory.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int i) {
|
|
||||||
return 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.eventLayout.setVisibility(View.GONE);
|
||||||
holder.bubbleLayout.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.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE);
|
||||||
holder.messageText.setVisibility(View.GONE);
|
holder.messageText.setVisibility(View.GONE);
|
||||||
holder.messageImage.setVisibility(View.GONE);
|
holder.messageImage.setVisibility(View.GONE);
|
||||||
|
@ -197,18 +159,16 @@ public class ChatEventsAdapter extends ListSelectionAdapter {
|
||||||
|
|
||||||
if (isEditionEnabled()) {
|
if (isEditionEnabled()) {
|
||||||
holder.delete.setOnCheckedChangeListener(null);
|
holder.delete.setOnCheckedChangeListener(null);
|
||||||
holder.delete.setChecked(getSelectedItemsPosition().contains(i));
|
holder.delete.setChecked(isSelected(position));
|
||||||
holder.delete.setTag(i);
|
holder.delete.setTag(position);
|
||||||
holder.delete.setOnCheckedChangeListener(getDeleteListener());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventLog event = (EventLog)getItem(i);
|
|
||||||
if (event.getType() == EventLog.Type.ConferenceChatMessage) {
|
if (event.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||||
holder.bubbleLayout.setVisibility(View.VISIBLE);
|
holder.bubbleLayout.setVisibility(View.VISIBLE);
|
||||||
final ChatMessage message = event.getChatMessage();
|
final ChatMessage message = event.getChatMessage();
|
||||||
|
|
||||||
if (i > 0 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
|
if (position > 0 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
|
||||||
EventLog previousEvent = (EventLog)getItem(i-1);
|
EventLog previousEvent = (EventLog)getItem(position-1);
|
||||||
if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) {
|
if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||||
ChatMessage previousMessage = previousEvent.getChatMessage();
|
ChatMessage previousMessage = previousEvent.getChatMessage();
|
||||||
if (previousMessage.getFromAddress().weakEqual(message.getFromAddress())) {
|
if (previousMessage.getFromAddress().weakEqual(message.getFromAddress())) {
|
||||||
|
@ -269,6 +229,7 @@ public class ChatEventsAdapter extends ListSelectionAdapter {
|
||||||
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI));
|
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//layoutParams allow bubbles alignment during selection mode
|
||||||
if (isEditionEnabled()) {
|
if (isEditionEnabled()) {
|
||||||
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
|
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
|
||||||
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
|
||||||
|
@ -437,8 +398,48 @@ public class ChatEventsAdapter extends ListSelectionAdapter {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return view;
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return this.mHistory.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToHistory(EventLog log) {
|
||||||
|
mHistory.add(log);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContacts(ArrayList<LinphoneContact> participants) {
|
||||||
|
mParticipants = participants;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(EventLog[] history) {
|
||||||
|
mHistory = new ArrayList<>(Arrays.asList(history));
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
for (EventLog event : mHistory) {
|
||||||
|
if (event.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||||
|
ChatMessage message = event.getChatMessage();
|
||||||
|
message.setListener(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mHistory.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return this.mHistory.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getItem(int i) {
|
||||||
|
return mHistory.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeItem(int i) {
|
||||||
|
mHistory.remove(i);
|
||||||
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadBitmap(String path, ImageView imageView) {
|
private void loadBitmap(String path, ImageView imageView) {
|
||||||
|
|
|
@ -20,68 +20,82 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
package org.linphone.chat;
|
package org.linphone.chat;
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
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.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.RelativeLayout;
|
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.LinphoneManager;
|
||||||
import org.linphone.R;
|
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.ChatMessage;
|
||||||
import org.linphone.core.ChatRoom;
|
import org.linphone.core.ChatRoom;
|
||||||
|
import org.linphone.core.ChatRoomListenerStub;
|
||||||
import org.linphone.core.Core;
|
import org.linphone.core.Core;
|
||||||
import org.linphone.core.CoreListenerStub;
|
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.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST;
|
import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST;
|
||||||
|
|
||||||
public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ListSelectionHelper.DeleteListener {
|
public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ChatRoomsAdapter.ChatRoomViewHolder.ClickListener, SelectableHelper.DeleteListener {
|
||||||
private LayoutInflater mInflater;
|
|
||||||
private ListView mChatRoomsList;
|
private RecyclerView mChatRoomsList;
|
||||||
private TextView mNoChatHistory;
|
|
||||||
private ImageView mNewDiscussionButton, mBackToCallButton;
|
private ImageView mNewDiscussionButton, mBackToCallButton;
|
||||||
private ChatRoomsAdapter mChatRoomsAdapter;
|
private ChatRoomsAdapter mChatRoomsAdapter;
|
||||||
private CoreListenerStub mListener;
|
private CoreListenerStub mListener;
|
||||||
private ListSelectionHelper mSelectionHelper;
|
|
||||||
private RelativeLayout mWaitLayout;
|
private RelativeLayout mWaitLayout;
|
||||||
private int mChatRoomDeletionPendingCount;
|
private int mChatRoomDeletionPendingCount;
|
||||||
private ChatRoomListenerStub mChatRoomListener;
|
private ChatRoomListenerStub mChatRoomListener;
|
||||||
|
private Context mContext;
|
||||||
|
public List<ChatRoom> mRooms;
|
||||||
|
private SelectableHelper mSelectionHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
mInflater = inflater;
|
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
mRooms = new ArrayList<>(Arrays.asList(LinphoneManager.getLc().getChatRooms()));
|
||||||
|
|
||||||
|
this.mContext = getActivity().getApplicationContext();
|
||||||
View view = inflater.inflate(R.layout.chatlist, container, false);
|
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.setAdapter(mChatRoomsAdapter);
|
||||||
mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog);
|
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);
|
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() {
|
mNewDiscussionButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
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() {
|
mBackToCallButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
@ -129,18 +142,36 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return view;
|
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() {
|
private void refreshChatRoomsList() {
|
||||||
mChatRoomsAdapter.refresh();
|
mChatRoomsAdapter.refresh();
|
||||||
mNoChatHistory.setVisibility(mChatRoomsAdapter.getCount() == 0 ? View.VISIBLE : View.GONE);
|
//mNoChatHistory.setVisibility(mChatRoomsAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayFirstChat() {
|
public void displayFirstChat() {
|
||||||
ChatRoomsAdapter adapter = (ChatRoomsAdapter)mChatRoomsList.getAdapter();
|
ChatRoomsAdapter adapter = (ChatRoomsAdapter)mChatRoomsList.getAdapter();
|
||||||
if (adapter != null && adapter.getCount() > 0) {
|
if (adapter != null && adapter.getItemCount() > 0) {
|
||||||
ChatRoom room = (ChatRoom) adapter.getItem(0);
|
ChatRoom room = (ChatRoom) adapter.getItem(0);
|
||||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
|
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
|
||||||
} else {
|
} else {
|
||||||
|
@ -156,7 +187,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
||||||
if (LinphoneManager.getLc().getCallsNb() > 0) {
|
if (LinphoneManager.getLc().getCallsNb() > 0) {
|
||||||
mBackToCallButton.setVisibility(View.VISIBLE);
|
mBackToCallButton.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
mBackToCallButton.setVisibility(View.INVISIBLE);
|
mBackToCallButton.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LinphoneActivity.isInstanciated()) {
|
if (LinphoneActivity.isInstanciated()) {
|
||||||
|
@ -181,6 +212,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
||||||
ContactsManager.removeContactsListener(this);
|
ContactsManager.removeContactsListener(this);
|
||||||
mChatRoomsAdapter.clear();
|
mChatRoomsAdapter.clear();
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -208,7 +240,6 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
||||||
if (mChatRoomDeletionPendingCount > 0) {
|
if (mChatRoomDeletionPendingCount > 0) {
|
||||||
mWaitLayout.setVisibility(View.VISIBLE);
|
mWaitLayout.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
LinphoneActivity.instance().refreshMissedChatCountDisplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -218,9 +249,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
||||||
|
|
||||||
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
|
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
adapter.notifyDataSetInvalidated();
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ package org.linphone.chat;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.graphics.Typeface;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -37,13 +36,11 @@ import org.linphone.activities.LinphoneActivity;
|
||||||
import org.linphone.contacts.ContactsManager;
|
import org.linphone.contacts.ContactsManager;
|
||||||
import org.linphone.contacts.LinphoneContact;
|
import org.linphone.contacts.LinphoneContact;
|
||||||
import org.linphone.core.Address;
|
import org.linphone.core.Address;
|
||||||
import org.linphone.core.ChatMessage;
|
|
||||||
import org.linphone.core.ChatRoom;
|
import org.linphone.core.ChatRoom;
|
||||||
import org.linphone.core.ChatRoomCapabilities;
|
import org.linphone.core.ChatRoomCapabilities;
|
||||||
import org.linphone.core.ChatRoomListenerStub;
|
import org.linphone.core.ChatRoomListenerStub;
|
||||||
import org.linphone.core.EventLog;
|
import org.linphone.ui.SelectableAdapter;
|
||||||
import org.linphone.ui.ListSelectionAdapter;
|
import org.linphone.ui.SelectableHelper;
|
||||||
import org.linphone.ui.ListSelectionHelper;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -51,9 +48,9 @@ import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
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 lastMessageSenderView;
|
||||||
public TextView lastMessageView;
|
public TextView lastMessageView;
|
||||||
public TextView date;
|
public TextView date;
|
||||||
|
@ -61,39 +58,133 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
||||||
public TextView unreadMessages;
|
public TextView unreadMessages;
|
||||||
public CheckBox delete;
|
public CheckBox delete;
|
||||||
public ImageView contactPicture;
|
public ImageView contactPicture;
|
||||||
|
public Context mContext;
|
||||||
|
public ChatRoom mRoom;
|
||||||
|
public ClickListener listener;
|
||||||
|
|
||||||
public ChatRoomViewHolder(View view) {
|
public ChatRoomViewHolder(Context context,View itemView, ClickListener listener) {
|
||||||
lastMessageSenderView = view.findViewById(R.id.lastMessageSender);
|
super(itemView);
|
||||||
lastMessageView = view.findViewById(R.id.lastMessage);
|
this.mContext= context;
|
||||||
date = view.findViewById(R.id.date);
|
this.lastMessageSenderView = itemView.findViewById(R.id.lastMessageSender);
|
||||||
displayName = view.findViewById(R.id.sipUri);
|
this.lastMessageView = itemView.findViewById(R.id.lastMessage);
|
||||||
unreadMessages = view.findViewById(R.id.unreadMessages);
|
this.date = itemView.findViewById(R.id.date);
|
||||||
delete = view.findViewById(R.id.delete_chatroom);
|
this.displayName = itemView.findViewById(R.id.sipUri);
|
||||||
contactPicture = view.findViewById(R.id.contact_picture);
|
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 Context mContext;
|
||||||
private List<ChatRoom> mRooms;
|
public List<ChatRoom> mRooms;
|
||||||
private LayoutInflater mLayoutInflater;
|
private static Bitmap mDefaultBitmap;
|
||||||
private Bitmap mDefaultBitmap, mDefaultGroupBitmap;
|
//private Bitmap mDefaultGroupBitmap;
|
||||||
private ChatRoomListenerStub mListener;
|
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);
|
super(helper);
|
||||||
mContext = context;
|
this.clickListener = clickListener;
|
||||||
mLayoutInflater = inflater;
|
this.mRooms = mRooms;
|
||||||
mRooms = new ArrayList<>();
|
this.mContext = context;
|
||||||
|
this.itemResource = itemResource;
|
||||||
mDefaultBitmap = ContactsManager.getInstance().getDefaultAvatarBitmap();
|
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() {
|
public void refresh() {
|
||||||
|
@ -114,6 +205,7 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
||||||
room.removeListener(mListener);
|
room.removeListener(mListener);
|
||||||
}
|
}
|
||||||
mRooms.clear();
|
mRooms.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,8 +213,8 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getItemCount() {
|
||||||
return mRooms.size();
|
return this.mRooms.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -134,121 +226,4 @@ public class ChatRoomsAdapter extends ListSelectionAdapter {
|
||||||
public long getItemId(int position) {
|
public long getItemId(int position) {
|
||||||
return 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.Environment;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
|
@ -45,12 +47,10 @@ import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager;
|
import org.linphone.LinphoneManager;
|
||||||
|
@ -61,6 +61,7 @@ import org.linphone.activities.LinphoneActivity;
|
||||||
import org.linphone.compatibility.Compatibility;
|
import org.linphone.compatibility.Compatibility;
|
||||||
import org.linphone.contacts.ContactAddress;
|
import org.linphone.contacts.ContactAddress;
|
||||||
import org.linphone.contacts.ContactsManager;
|
import org.linphone.contacts.ContactsManager;
|
||||||
|
import org.linphone.contacts.ContactsUpdatedListener;
|
||||||
import org.linphone.contacts.LinphoneContact;
|
import org.linphone.contacts.LinphoneContact;
|
||||||
import org.linphone.core.Address;
|
import org.linphone.core.Address;
|
||||||
import org.linphone.core.ChatMessage;
|
import org.linphone.core.ChatMessage;
|
||||||
|
@ -73,10 +74,9 @@ import org.linphone.core.EventLog;
|
||||||
import org.linphone.core.Factory;
|
import org.linphone.core.Factory;
|
||||||
import org.linphone.core.LimeState;
|
import org.linphone.core.LimeState;
|
||||||
import org.linphone.core.Participant;
|
import org.linphone.core.Participant;
|
||||||
import org.linphone.contacts.ContactsUpdatedListener;
|
|
||||||
import org.linphone.core.Reason;
|
import org.linphone.core.Reason;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
import org.linphone.ui.ListSelectionHelper;
|
import org.linphone.ui.SelectableHelper;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -85,7 +85,7 @@ import java.util.List;
|
||||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||||
import static org.linphone.fragments.FragmentsAvailable.CHAT;
|
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 static final int ADD_PHOTO = 1337;
|
||||||
|
|
||||||
private ImageView mBackButton, mCallButton, mBackToCallButton, mGroupInfosButton;
|
private ImageView mBackButton, mCallButton, mBackToCallButton, mGroupInfosButton;
|
||||||
|
@ -93,10 +93,10 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
private TextView mRoomLabel, mParticipantsLabel, mRemoteComposing;
|
private TextView mRoomLabel, mParticipantsLabel, mRemoteComposing;
|
||||||
private EditText mMessageTextToSend;
|
private EditText mMessageTextToSend;
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
private ListView mChatEventsList;
|
private RecyclerView mChatEventsList;
|
||||||
private LinearLayout mFilesUploadLayout;
|
private LinearLayout mFilesUploadLayout;
|
||||||
private ListSelectionHelper mSelectionHelper;
|
private SelectableHelper mSelectionHelper;
|
||||||
|
private Context mContext;
|
||||||
private ViewTreeObserver.OnGlobalLayoutListener mKeyboardListener;
|
private ViewTreeObserver.OnGlobalLayoutListener mKeyboardListener;
|
||||||
private Uri mImageToUploadUri;
|
private Uri mImageToUploadUri;
|
||||||
private ChatEventsAdapter mEventsAdapter;
|
private ChatEventsAdapter mEventsAdapter;
|
||||||
|
@ -104,7 +104,8 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
private Address mRemoteSipAddress, mRemoteParticipantAddress;
|
private Address mRemoteSipAddress, mRemoteParticipantAddress;
|
||||||
private ChatRoom mChatRoom;
|
private ChatRoom mChatRoom;
|
||||||
private ArrayList<LinphoneContact> mParticipants;
|
private ArrayList<LinphoneContact> mParticipants;
|
||||||
|
private LinearLayoutManager layoutManager;
|
||||||
|
private int mContextMenuMessagePosition;
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -116,10 +117,9 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
mRemoteSipAddress = LinphoneManager.getLc().createAddress(mRemoteSipUri);
|
mRemoteSipAddress = LinphoneManager.getLc().createAddress(mRemoteSipUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
mInflater = inflater;
|
this.mContext = getActivity().getApplicationContext();
|
||||||
View view = inflater.inflate(R.layout.chat, container, false);
|
View view = inflater.inflate(R.layout.chat, container, false);
|
||||||
|
|
||||||
mSelectionHelper = new ListSelectionHelper(view, this);
|
|
||||||
|
|
||||||
mBackButton = view.findViewById(R.id.back);
|
mBackButton = view.findViewById(R.id.back);
|
||||||
mBackButton.setOnClickListener(new View.OnClickListener() {
|
mBackButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@ -213,7 +213,9 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
mRemoteComposing = view.findViewById(R.id.remote_composing);
|
mRemoteComposing = view.findViewById(R.id.remote_composing);
|
||||||
|
|
||||||
mChatEventsList = view.findViewById(R.id.chat_message_list);
|
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) {
|
if (getArguments() != null) {
|
||||||
String fileSharedUri = getArguments().getString("fileSharedUri");
|
String fileSharedUri = getArguments().getString("fileSharedUri");
|
||||||
|
@ -233,7 +235,6 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
if (getArguments().getString("messageDraft") != null)
|
if (getArguments().getString("messageDraft") != null)
|
||||||
mMessageTextToSend.setText(getArguments().getString("messageDraft"));
|
mMessageTextToSend.setText(getArguments().getString("messageDraft"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +258,6 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
initChatRoom();
|
initChatRoom();
|
||||||
displayChatRoomHeader();
|
displayChatRoomHeader();
|
||||||
displayChatRoomHistory();
|
displayChatRoomHistory();
|
||||||
|
|
||||||
LinphoneManager.getInstance().setCurrentChatRoomAddress(mRemoteSipAddress);
|
LinphoneManager.getInstance().setCurrentChatRoomAddress(mRemoteSipAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,12 +347,15 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
super.onCreateContextMenu(menu, v, menuInfo);
|
||||||
|
|
||||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
ChatBubbleViewHolder holder = (ChatBubbleViewHolder) v.getTag();
|
||||||
EventLog event = (EventLog) mEventsAdapter.getItem(info.position);
|
mContextMenuMessagePosition = holder.getAdapterPosition();
|
||||||
|
|
||||||
|
EventLog event = (EventLog) mEventsAdapter.getItem(mContextMenuMessagePosition);
|
||||||
if (event.getType() != EventLog.Type.ConferenceChatMessage) {
|
if (event.getType() != EventLog.Type.ConferenceChatMessage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -365,8 +368,8 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
inflater.inflate(R.menu.chat_bubble_menu, menu);
|
inflater.inflate(R.menu.chat_bubble_menu, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
if (!message.isOutgoing() && 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
|
// 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);
|
menu.removeItem(R.id.imdn_infos);
|
||||||
}
|
}
|
||||||
if (!message.hasTextContent()) {
|
if (!message.hasTextContent()) {
|
||||||
|
@ -377,9 +380,9 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onContextItemSelected(MenuItem item) {
|
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) {
|
if (event.getType() != EventLog.Type.ConferenceChatMessage) {
|
||||||
return super.onContextItemSelected(item);
|
return super.onContextItemSelected(item);
|
||||||
}
|
}
|
||||||
|
@ -388,7 +391,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
String messageId = message.getMessageId();
|
String messageId = message.getMessageId();
|
||||||
|
|
||||||
if (item.getItemId() == R.id.resend) {
|
if (item.getItemId() == R.id.resend) {
|
||||||
mEventsAdapter.removeItem(info.position);
|
mEventsAdapter.removeItem(mContextMenuMessagePosition);
|
||||||
message.resend();
|
message.resend();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +409,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
}
|
}
|
||||||
if (item.getItemId() == R.id.delete_message) {
|
if (item.getItemId() == R.id.delete_message) {
|
||||||
mChatRoom.deleteMessage(message);
|
mChatRoom.deleteMessage(message);
|
||||||
mEventsAdapter.removeItem(info.position);
|
mEventsAdapter.removeItem(mContextMenuMessagePosition);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.onContextItemSelected(item);
|
return super.onContextItemSelected(item);
|
||||||
|
@ -548,26 +551,33 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayChatRoomHistory() {
|
private void displayChatRoomHistory() {
|
||||||
|
|
||||||
if (mChatRoom == null) return;
|
if (mChatRoom == null) return;
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
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 {
|
} 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);
|
mSelectionHelper.setAdapter(mEventsAdapter);
|
||||||
mChatEventsList.setAdapter(mEventsAdapter);
|
mChatEventsList.setAdapter(mEventsAdapter);
|
||||||
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scrollToBottom() {
|
public void scrollToBottom() {
|
||||||
if (((mChatEventsList.getLastVisiblePosition() >= (mEventsAdapter.getCount() - 1)) && (mChatEventsList.getFirstVisiblePosition() <= (mEventsAdapter.getCount() - 1)))) {
|
mChatEventsList.getLayoutManager().scrollToPosition(mEventsAdapter.getCount() - 1);
|
||||||
mChatEventsList.setSelection(mEventsAdapter.getCount() - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRemoteSipUri() {
|
public String getRemoteSipUri() {
|
||||||
return mRemoteSipUri;
|
return mRemoteSipUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemClicked(int position) {
|
||||||
|
if (mEventsAdapter.isEditionEnabled()) {
|
||||||
|
mEventsAdapter.toggleSelection(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File transfer related
|
* File transfer related
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
package org.linphone.chat;
|
package org.linphone.chat;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -32,66 +34,64 @@ import org.linphone.R;
|
||||||
import org.linphone.activities.LinphoneActivity;
|
import org.linphone.activities.LinphoneActivity;
|
||||||
import org.linphone.contacts.ContactAddress;
|
import org.linphone.contacts.ContactAddress;
|
||||||
import org.linphone.contacts.LinphoneContact;
|
import org.linphone.contacts.LinphoneContact;
|
||||||
|
import org.linphone.contacts.SearchContactsListAdapter;
|
||||||
import org.linphone.core.ChatRoom;
|
import org.linphone.core.ChatRoom;
|
||||||
import org.linphone.core.Participant;
|
import org.linphone.core.Participant;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class GroupInfoAdapter extends BaseAdapter {
|
public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.ViewHolder> {
|
||||||
private LayoutInflater mInflater;
|
|
||||||
|
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 List<ContactAddress> mItems;
|
||||||
private View.OnClickListener mDeleteListener;
|
private View.OnClickListener mDeleteListener;
|
||||||
private boolean mHideAdminFeatures;
|
private boolean mHideAdminFeatures;
|
||||||
private ChatRoom mChatRoom;
|
private ChatRoom mChatRoom;
|
||||||
|
public ImageView avatar;
|
||||||
|
|
||||||
public GroupInfoAdapter(LayoutInflater inflater, List<ContactAddress> items, boolean hideAdminFeatures, boolean isCreation) {
|
public GroupInfoAdapter(List<ContactAddress> items, boolean hideAdminFeatures, boolean isCreation) {
|
||||||
mInflater = inflater;
|
|
||||||
mItems = items;
|
mItems = items;
|
||||||
mHideAdminFeatures = hideAdminFeatures || isCreation;
|
mHideAdminFeatures = hideAdminFeatures || isCreation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChatRoom(ChatRoom room) {
|
@NonNull
|
||||||
mChatRoom = room;
|
@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
|
@Override
|
||||||
public int getCount() {
|
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||||
return mItems.size();
|
final ContactAddress ca = (ContactAddress)getItem(position);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getItem(int i) {
|
|
||||||
return mItems.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int i) {
|
|
||||||
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();
|
LinphoneContact c = ca.getContact();
|
||||||
|
this.avatar=holder.avatar;
|
||||||
TextView name = view.findViewById(R.id.name);
|
holder.name.setText((c.getFullName() != null) ? c.getFullName() :
|
||||||
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());
|
(ca.getDisplayName() != null) ? ca.getDisplayName() : ca.getUsername());
|
||||||
if (c.hasPhoto()) {
|
if (c.hasPhoto()) {
|
||||||
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), avatar, c.getThumbnailUri());
|
LinphoneUtils.setThumbnailPictureFromUri(LinphoneActivity.instance(), avatar, c.getThumbnailUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete.setOnClickListener(new View.OnClickListener() {
|
holder.delete.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (mDeleteListener != null) {
|
if (mDeleteListener != null) {
|
||||||
|
@ -99,34 +99,34 @@ public class GroupInfoAdapter extends BaseAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
delete.setTag(ca);
|
holder.delete.setTag(ca);
|
||||||
|
|
||||||
isAdmin.setVisibility(ca.isAdmin() ? View.VISIBLE : View.GONE);
|
holder.isAdmin.setVisibility(ca.isAdmin() ? View.VISIBLE : View.GONE);
|
||||||
isNotAdmin.setVisibility(ca.isAdmin() ? View.GONE : View.VISIBLE);
|
holder.isNotAdmin.setVisibility(ca.isAdmin() ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
isAdmin.setOnClickListener(new View.OnClickListener() {
|
holder.isAdmin.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
isNotAdmin.setVisibility(View.VISIBLE);
|
holder.isNotAdmin.setVisibility(View.VISIBLE);
|
||||||
isAdmin.setVisibility(View.GONE);
|
holder.isAdmin.setVisibility(View.GONE);
|
||||||
ca.setAdmin(false);
|
ca.setAdmin(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
isNotAdmin.setOnClickListener(new View.OnClickListener() {
|
holder.isNotAdmin.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
isNotAdmin.setVisibility(View.GONE);
|
holder.isNotAdmin.setVisibility(View.GONE);
|
||||||
isAdmin.setVisibility(View.VISIBLE);
|
holder.isAdmin.setVisibility(View.VISIBLE);
|
||||||
ca.setAdmin(true);
|
ca.setAdmin(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
delete.setVisibility(View.VISIBLE);
|
holder.delete.setVisibility(View.VISIBLE);
|
||||||
if (mHideAdminFeatures) {
|
if (mHideAdminFeatures) {
|
||||||
delete.setVisibility(View.INVISIBLE);
|
holder.delete.setVisibility(View.INVISIBLE);
|
||||||
isAdmin.setOnClickListener(null); // Do not allow not admin to remove it's rights but display admins
|
holder.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
|
holder.isNotAdmin.setVisibility(View.GONE); // Hide not admin button for not admin participants
|
||||||
} else if (mChatRoom != null) {
|
} else if (mChatRoom != null) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (Participant p : mChatRoom.getParticipants()) {
|
for (Participant p : mChatRoom.getParticipants()) {
|
||||||
|
@ -136,11 +136,31 @@ public class GroupInfoAdapter extends BaseAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
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
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mItems.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChatRoom(ChatRoom room) {
|
||||||
|
mChatRoom = room;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return mItems.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getItem(int i) {
|
||||||
|
return mItems.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int i) {
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnDeleteClickListener(View.OnClickListener onClickListener) {
|
public void setOnDeleteClickListener(View.OnClickListener onClickListener) {
|
||||||
|
@ -154,6 +174,6 @@ public class GroupInfoAdapter extends BaseAdapter {
|
||||||
|
|
||||||
public void setAdminFeaturesVisible(boolean visible) {
|
public void setAdminFeaturesVisible(boolean visible) {
|
||||||
mHideAdminFeatures = !visible;
|
mHideAdminFeatures = !visible;
|
||||||
notifyDataSetInvalidated();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,11 @@ package org.linphone.chat;
|
||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
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.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -32,7 +36,6 @@ import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager;
|
import org.linphone.LinphoneManager;
|
||||||
|
@ -61,7 +64,9 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
private Address mGroupChatRoomAddress;
|
private Address mGroupChatRoomAddress;
|
||||||
private EditText mSubjectField;
|
private EditText mSubjectField;
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
private ListView mParticipantsList;
|
|
||||||
|
private RecyclerView mParticipantsList;
|
||||||
|
|
||||||
private LinearLayout mLeaveGroupButton;
|
private LinearLayout mLeaveGroupButton;
|
||||||
private RelativeLayout mWaitLayout;
|
private RelativeLayout mWaitLayout;
|
||||||
private GroupInfoAdapter mAdapter;
|
private GroupInfoAdapter mAdapter;
|
||||||
|
@ -73,6 +78,8 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
private Dialog mAdminStateChangedDialog;
|
private Dialog mAdminStateChangedDialog;
|
||||||
private ChatRoomListenerStub mChatRoomCreationListener;
|
private ChatRoomListenerStub mChatRoomCreationListener;
|
||||||
private Bundle mShareInfos;
|
private Bundle mShareInfos;
|
||||||
|
private Context mContext;
|
||||||
|
private LinearLayoutManager layoutManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
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()) {
|
if (getArguments() == null || getArguments().isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
this.mContext = getActivity().getApplicationContext();
|
||||||
|
|
||||||
mParticipants = (ArrayList<ContactAddress>) getArguments().getSerializable("ContactAddress");
|
mParticipants = (ArrayList<ContactAddress>) getArguments().getSerializable("ContactAddress");
|
||||||
|
|
||||||
mGroupChatRoomAddress = null;
|
mGroupChatRoomAddress = null;
|
||||||
|
@ -105,7 +114,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
mParticipantsList = view.findViewById(R.id.chat_room_participants);
|
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() {
|
mAdapter.setOnDeleteClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
@ -118,6 +127,15 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
});
|
});
|
||||||
mParticipantsList.setAdapter(mAdapter);
|
mParticipantsList.setAdapter(mAdapter);
|
||||||
mAdapter.setChatRoom(mChatRoom);
|
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 fileSharedUri = getArguments().getString("fileSharedUri");
|
||||||
String messageDraft = getArguments().getString("messageDraft");
|
String messageDraft = getArguments().getString("messageDraft");
|
||||||
|
|
|
@ -47,7 +47,7 @@ import org.linphone.core.ChatRoom;
|
||||||
import org.linphone.core.Core;
|
import org.linphone.core.Core;
|
||||||
import org.linphone.core.ParticipantImdnState;
|
import org.linphone.core.ParticipantImdnState;
|
||||||
|
|
||||||
public class ImdnFragment extends Fragment {
|
public class ImdnFragment extends Fragment{
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
private LinearLayout mRead, mReadHeader, mDelivered, mDeliveredHeader, mSent, mSentHeader, mUndelivered, mUndeliveredHeader;
|
private LinearLayout mRead, mReadHeader, mDelivered, mDeliveredHeader, mSent, mSentHeader, mUndelivered, mUndeliveredHeader;
|
||||||
private ImageView mBackButton;
|
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.app.Fragment;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
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.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AbsListView;
|
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
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.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.SectionIndexer;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.linphone.fragments.FragmentsAvailable;
|
|
||||||
import org.linphone.LinphoneManager;
|
import org.linphone.LinphoneManager;
|
||||||
import org.linphone.LinphoneUtils;
|
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.activities.LinphoneActivity;
|
import org.linphone.activities.LinphoneActivity;
|
||||||
|
import org.linphone.fragments.FragmentsAvailable;
|
||||||
|
import org.linphone.ui.SelectableHelper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ContactsListFragment extends Fragment implements OnClickListener, OnItemClickListener, ContactsUpdatedListener {
|
public class ContactsListFragment extends Fragment implements OnItemClickListener, ContactsUpdatedListener, ContactsListAdapter.ViewHolder.ClickListener ,SelectableHelper.DeleteListener {
|
||||||
private LayoutInflater mInflater;
|
private RecyclerView contactsList;
|
||||||
private ListView contactsList;
|
|
||||||
private TextView noSipContact, noContact;
|
private TextView noSipContact, noContact;
|
||||||
private ImageView allContacts, linphoneContacts, newContact, edit, selectAll, deselectAll, delete, cancel;
|
private ImageView allContacts, linphoneContacts, newContact, edit;
|
||||||
private boolean onlyDisplayLinphoneContacts, isEditMode, isSearchMode;
|
private boolean onlyDisplayLinphoneContacts;
|
||||||
private View allContactsSelected, linphoneContactsSelected;
|
private View allContactsSelected, linphoneContactsSelected;
|
||||||
private LinearLayout editList, topbar;
|
|
||||||
private int lastKnownPosition;
|
private int lastKnownPosition;
|
||||||
private boolean editOnClick = false, editConsumed = false, onlyDisplayChatAddress = false;
|
private boolean editOnClick = false, editConsumed = false, onlyDisplayChatAddress = false;
|
||||||
private String sipAddressToAdd, displayName = null;
|
private String sipAddressToAdd, displayName = null;
|
||||||
private ImageView clearSearchField;
|
private ImageView clearSearchField;
|
||||||
private EditText searchField;
|
private EditText searchField;
|
||||||
private ProgressBar contactsFetchInProgress;
|
private ProgressBar contactsFetchInProgress;
|
||||||
|
private LinearLayoutManager layoutManager;
|
||||||
|
private Context mContext;
|
||||||
|
private SelectableHelper mSelectionHelper;
|
||||||
|
private ContactsListAdapter mContactAdapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
mInflater = inflater;
|
|
||||||
View view = inflater.inflate(R.layout.contacts_list, container, false);
|
View view = inflater.inflate(R.layout.contacts_list, container, false);
|
||||||
|
mContext = getActivity().getApplicationContext();
|
||||||
|
mSelectionHelper = new SelectableHelper(view, this);
|
||||||
|
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
editOnClick = getArguments().getBoolean("EditOnClick");
|
editOnClick = getArguments().getBoolean("EditOnClick");
|
||||||
|
@ -86,46 +80,64 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
||||||
|
|
||||||
noSipContact = (TextView) view.findViewById(R.id.noSipContact);
|
noSipContact = (TextView) view.findViewById(R.id.noSipContact);
|
||||||
noContact = (TextView) view.findViewById(R.id.noContact);
|
noContact = (TextView) view.findViewById(R.id.noContact);
|
||||||
|
contactsList = view.findViewById(R.id.contactsList);
|
||||||
contactsList = (ListView) view.findViewById(R.id.contactsList);
|
|
||||||
contactsList.setOnItemClickListener(this);
|
|
||||||
|
|
||||||
allContacts = (ImageView) view.findViewById(R.id.all_contacts);
|
allContacts = (ImageView) view.findViewById(R.id.all_contacts);
|
||||||
allContacts.setOnClickListener(this);
|
|
||||||
|
|
||||||
linphoneContacts = (ImageView) view.findViewById(R.id.linphone_contacts);
|
linphoneContacts = (ImageView) view.findViewById(R.id.linphone_contacts);
|
||||||
linphoneContacts.setOnClickListener(this);
|
|
||||||
|
|
||||||
allContactsSelected = view.findViewById(R.id.all_contacts_select);
|
allContactsSelected = view.findViewById(R.id.all_contacts_select);
|
||||||
linphoneContactsSelected = view.findViewById(R.id.linphone_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);
|
newContact = (ImageView) view.findViewById(R.id.newContact);
|
||||||
newContact.setOnClickListener(this);
|
|
||||||
newContact.setEnabled(LinphoneManager.getLc().getCallsNb() == 0);
|
|
||||||
|
|
||||||
|
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.setEnabled(LinphoneManager.getLc().getCallsNb() == 0);
|
||||||
allContacts.setEnabled(onlyDisplayLinphoneContacts);
|
allContacts.setEnabled(onlyDisplayLinphoneContacts);
|
||||||
linphoneContacts.setEnabled(!allContacts.isEnabled());
|
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 = (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 = (EditText) view.findViewById(R.id.searchField);
|
||||||
searchField.addTextChangedListener(new TextWatcher() {
|
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 = (ProgressBar) view.findViewById(R.id.contactsFetchInProgress);
|
||||||
contactsFetchInProgress.setVisibility(View.VISIBLE);
|
contactsFetchInProgress.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
return view;
|
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(){
|
public void displayFirstContact(){
|
||||||
if (contactsList != null && contactsList.getAdapter() != null && contactsList.getAdapter().getCount() > 0) {
|
if (contactsList != null && contactsList.getAdapter() != null && contactsList.getAdapter().getItemCount() > 0) {
|
||||||
LinphoneActivity.instance().displayContact((LinphoneContact) contactsList.getAdapter().getItem(0), false);
|
ContactsListAdapter mAdapt = (ContactsListAdapter)contactsList.getAdapter();
|
||||||
|
LinphoneActivity.instance().displayContact((LinphoneContact) mAdapt.getItem(0), false);
|
||||||
} else {
|
} else {
|
||||||
LinphoneActivity.instance().displayEmptyFragment();
|
LinphoneActivity.instance().displayEmptyFragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchContacts() {
|
|
||||||
searchContacts(searchField.getText().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void searchContacts(String search) {
|
private void searchContacts(String search) {
|
||||||
|
boolean isEditionEnabled = false;
|
||||||
if (search == null || search.length() == 0) {
|
if (search == null || search.length() == 0) {
|
||||||
changeContactsAdapter();
|
changeContactsAdapter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
changeContactsToggle();
|
changeContactsToggle();
|
||||||
|
mContactAdapter.setmIsSearchMode(true);
|
||||||
|
|
||||||
isSearchMode = true;
|
List<LinphoneContact> listContact;
|
||||||
|
|
||||||
if (onlyDisplayLinphoneContacts) {
|
if (onlyDisplayLinphoneContacts) {
|
||||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
listContact = ContactsManager.getInstance().getSIPContacts(search);
|
||||||
contactsList.setAdapter(new ContactsListAdapter(ContactsManager.getInstance().getSIPContacts(search)));
|
|
||||||
} else {
|
} else {
|
||||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
listContact = ContactsManager.getInstance().getContacts(search);
|
||||||
contactsList.setAdapter(new ContactsListAdapter(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() {
|
private void changeContactsAdapter() {
|
||||||
changeContactsToggle();
|
changeContactsToggle();
|
||||||
|
List<LinphoneContact> listContact;
|
||||||
|
|
||||||
isSearchMode = false;
|
|
||||||
noSipContact.setVisibility(View.GONE);
|
noSipContact.setVisibility(View.GONE);
|
||||||
noContact.setVisibility(View.GONE);
|
noContact.setVisibility(View.GONE);
|
||||||
contactsList.setVisibility(View.VISIBLE);
|
contactsList.setVisibility(View.VISIBLE);
|
||||||
|
boolean isEditionEnabled = false;
|
||||||
ContactsListAdapter adapter;
|
if(searchField.getText().toString() == "") {
|
||||||
contactsList.setFastScrollEnabled(false);
|
|
||||||
if (onlyDisplayLinphoneContacts) {
|
if (onlyDisplayLinphoneContacts) {
|
||||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
listContact = ContactsManager.getInstance().getSIPContacts();
|
||||||
adapter = new ContactsListAdapter(ContactsManager.getInstance().getSIPContacts());
|
|
||||||
contactsList.setAdapter(adapter);
|
|
||||||
edit.setEnabled(true);
|
|
||||||
} else {
|
} else {
|
||||||
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
listContact = ContactsManager.getInstance().getContacts();
|
||||||
adapter = new ContactsListAdapter(ContactsManager.getInstance().getContacts());
|
|
||||||
contactsList.setAdapter(adapter);
|
|
||||||
edit.setEnabled(true);
|
|
||||||
}
|
}
|
||||||
contactsList.setFastScrollEnabled(true);
|
|
||||||
adapter.notifyDataSetInvalidated();
|
|
||||||
|
|
||||||
|
|
||||||
if (adapter.getCount() > 0) {
|
}else{
|
||||||
|
if (onlyDisplayLinphoneContacts) {
|
||||||
|
listContact = ContactsManager.getInstance().getSIPContacts(searchField.getText().toString());
|
||||||
|
} else {
|
||||||
|
listContact = ContactsManager.getInstance().getContacts(searchField.getText().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mContactAdapter != null && mContactAdapter.isEditionEnabled()) {
|
||||||
|
isEditionEnabled=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
contactsFetchInProgress.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
ContactsManager.getInstance().setLinphoneContactsPrefered(onlyDisplayLinphoneContacts);
|
ContactsManager.getInstance().setLinphoneContactsPrefered(onlyDisplayLinphoneContacts);
|
||||||
|
@ -386,11 +281,36 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
||||||
editConsumed = true;
|
editConsumed = true;
|
||||||
LinphoneActivity.instance().editContact(contact, sipAddressToAdd);
|
LinphoneActivity.instance().editContact(contact, sipAddressToAdd);
|
||||||
} else {
|
} else {
|
||||||
lastKnownPosition = contactsList.getFirstVisiblePosition();
|
lastKnownPosition = layoutManager.findFirstVisibleItemPosition();
|
||||||
LinphoneActivity.instance().displayContact(contact, onlyDisplayChatAddress);
|
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
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
@ -426,13 +346,11 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
||||||
return;
|
return;
|
||||||
ContactsListAdapter adapter = (ContactsListAdapter)contactsList.getAdapter();
|
ContactsListAdapter adapter = (ContactsListAdapter)contactsList.getAdapter();
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
contactsList.setFastScrollEnabled(false);
|
|
||||||
if (onlyDisplayLinphoneContacts) {
|
if (onlyDisplayLinphoneContacts) {
|
||||||
adapter.updateDataSet(ContactsManager.getInstance().getSIPContacts());
|
adapter.updateDataSet(ContactsManager.getInstance().getSIPContacts());
|
||||||
} else {
|
} else {
|
||||||
adapter.updateDataSet(ContactsManager.getInstance().getContacts());
|
adapter.updateDataSet(ContactsManager.getInstance().getContacts());
|
||||||
}
|
}
|
||||||
contactsList.setFastScrollEnabled(true);
|
|
||||||
contactsFetchInProgress.setVisibility(View.GONE);
|
contactsFetchInProgress.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,206 +361,22 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
||||||
} else {
|
} else {
|
||||||
changeContactsAdapter();
|
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);
|
|
||||||
} else {
|
|
||||||
holder.separator.setVisibility(View.VISIBLE);
|
|
||||||
String fullName = contact.getFullName();
|
|
||||||
if (fullName != null && !fullName.isEmpty()) {
|
|
||||||
holder.separatorText.setText(String.valueOf(fullName.charAt(0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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
|
@Override
|
||||||
public Object[] getSections() {
|
public void onDeleteSelection(Object[] objectsToDelete) {
|
||||||
return sections;
|
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 {
|
||||||
|
contact.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@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;
|
package org.linphone.contacts;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -40,30 +40,48 @@ import org.linphone.core.SearchResult;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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 name;
|
||||||
public TextView address;
|
public TextView address;
|
||||||
public ImageView linphoneContact;
|
public ImageView linphoneContact;
|
||||||
public ImageView isSelect;
|
public ImageView isSelect;
|
||||||
public ImageView avatar;
|
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);
|
name = view.findViewById(R.id.contact_name);
|
||||||
address = view.findViewById(R.id.contact_address);
|
address = view.findViewById(R.id.contact_address);
|
||||||
linphoneContact = view.findViewById(R.id.contact_linphone);
|
linphoneContact = view.findViewById(R.id.contact_linphone);
|
||||||
isSelect = view.findViewById(R.id.contact_is_select);
|
isSelect = view.findViewById(R.id.contact_is_select);
|
||||||
avatar = view.findViewById(R.id.contact_picture);
|
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> contacts;
|
||||||
private List<ContactAddress> contactsSelected;
|
private List<ContactAddress> contactsSelected;
|
||||||
private LayoutInflater mInflater;
|
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
private boolean mOnlySipContact = false;
|
private boolean mOnlySipContact = false;
|
||||||
private View.OnClickListener listener;
|
private ViewHolder.ClickListener listener;
|
||||||
|
|
||||||
public List<ContactAddress> getContacts() {
|
public List<ContactAddress> getContacts() {
|
||||||
return contacts;
|
return contacts;
|
||||||
|
@ -73,17 +91,78 @@ public class SearchContactsListAdapter extends BaseAdapter {
|
||||||
mOnlySipContact = enable;
|
mOnlySipContact = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setListener(View.OnClickListener listener) {
|
public void setListener(ViewHolder.ClickListener listener) {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchContactsListAdapter(List<ContactAddress> contactsList, LayoutInflater inflater, ProgressBar pB) {
|
public SearchContactsListAdapter(List<ContactAddress> contactsList, ProgressBar pB, ViewHolder.ClickListener clickListener) {
|
||||||
mInflater = inflater;
|
this.listener=clickListener;
|
||||||
progressBar = pB;
|
progressBar = pB;
|
||||||
setContactsSelectedList(null);
|
setContactsSelectedList(null);
|
||||||
setContactsList(contactsList);
|
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) {
|
private boolean contactIsSelected(ContactAddress ca) {
|
||||||
for (ContactAddress c : contactsSelected) {
|
for (ContactAddress c : contactsSelected) {
|
||||||
Address addr = c.getAddress();
|
Address addr = c.getAddress();
|
||||||
|
@ -160,11 +239,14 @@ public class SearchContactsListAdapter extends BaseAdapter {
|
||||||
return contacts.get(position);
|
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<>();
|
List<ContactAddress> result = new ArrayList<>();
|
||||||
|
|
||||||
String domain = "";
|
String domain = "";
|
||||||
|
@ -205,70 +287,5 @@ public class SearchContactsListAdapter extends BaseAdapter {
|
||||||
resultContactsSearch.setAdapter(this);
|
resultContactsSearch.setAdapter(this);
|
||||||
this.notifyDataSetChanged();
|
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.
|
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.app.Fragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
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.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AbsListView;
|
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
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.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
public class HistoryListFragment extends Fragment implements OnClickListener, OnItemClickListener, ContactsUpdatedListener {
|
import org.linphone.LinphoneManager;
|
||||||
private ListView historyList;
|
import org.linphone.R;
|
||||||
private LayoutInflater mInflater;
|
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 TextView noCallHistory, noMissedCallHistory;
|
||||||
private ImageView missedCalls, allCalls, edit, selectAll, deselectAll, delete, cancel;
|
private ImageView missedCalls, allCalls, edit;
|
||||||
private View allCallsSelected, missedCallsSelected;
|
private View allCallsSelected, missedCallsSelected;
|
||||||
private LinearLayout editList, topBar;
|
private boolean mOnlyDisplayMissedCalls, mIsEditMode;
|
||||||
private boolean onlyDisplayMissedCalls, isEditMode;
|
|
||||||
private List<CallLog> mLogs;
|
private List<CallLog> mLogs;
|
||||||
|
private CallHistoryAdapter mHistoryAdapter;
|
||||||
|
private LinearLayoutManager mLayoutManager;
|
||||||
|
private Context mContext;
|
||||||
|
private SelectableHelper mSelectionHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
mInflater = inflater;
|
|
||||||
View view = inflater.inflate(R.layout.history, container, false);
|
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);
|
noCallHistory = (TextView) view.findViewById(R.id.no_call_history);
|
||||||
noMissedCallHistory = (TextView) view.findViewById(R.id.no_missed_call_history);
|
noMissedCallHistory = (TextView) view.findViewById(R.id.no_missed_call_history);
|
||||||
|
|
||||||
historyList = (ListView) view.findViewById(R.id.history_list);
|
historyList = (RecyclerView) view.findViewById(R.id.history_list);
|
||||||
historyList.setOnItemClickListener(this);
|
|
||||||
|
|
||||||
delete = (ImageView) view.findViewById(R.id.delete);
|
mLayoutManager = new LinearLayoutManager(mContext);
|
||||||
delete.setOnClickListener(this);
|
historyList.setLayoutManager(mLayoutManager);
|
||||||
|
//Divider between items
|
||||||
editList = (LinearLayout) view.findViewById(R.id.edit_list);
|
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(historyList.getContext(),
|
||||||
topBar = (LinearLayout) view.findViewById(R.id.top_bar);
|
mLayoutManager.getOrientation());
|
||||||
|
dividerItemDecoration.setDrawable(mContext.getResources().getDrawable(R.drawable.divider));
|
||||||
cancel = (ImageView) view.findViewById(R.id.cancel);
|
historyList.addItemDecoration(dividerItemDecoration);
|
||||||
cancel.setOnClickListener(this);
|
|
||||||
|
|
||||||
allCalls = (ImageView) view.findViewById(R.id.all_calls);
|
allCalls = (ImageView) view.findViewById(R.id.all_calls);
|
||||||
allCalls.setOnClickListener(this);
|
allCalls.setOnClickListener(this);
|
||||||
|
@ -100,17 +92,10 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
||||||
|
|
||||||
missedCallsSelected = view.findViewById(R.id.missed_calls_select);
|
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);
|
allCalls.setEnabled(false);
|
||||||
onlyDisplayMissedCalls = false;
|
mOnlyDisplayMissedCalls = false;
|
||||||
|
|
||||||
edit = (ImageView) view.findViewById(R.id.edit);
|
edit = (ImageView) view.findViewById(R.id.edit);
|
||||||
edit.setOnClickListener(this);
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -119,13 +104,6 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
||||||
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
|
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(){
|
public void displayFirstLog(){
|
||||||
if (mLogs != null && mLogs.size() > 0) {
|
if (mLogs != null && mLogs.size() > 0) {
|
||||||
CallLog log = mLogs.get(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() {
|
private void removeNotMissedCallsFromLogs() {
|
||||||
if (onlyDisplayMissedCalls) {
|
if (mOnlyDisplayMissedCalls) {
|
||||||
List<CallLog> missedCalls = new ArrayList<CallLog>();
|
List<CallLog> missedCalls = new ArrayList<CallLog>();
|
||||||
for (CallLog log : mLogs) {
|
for (CallLog log : mLogs) {
|
||||||
if (log.getStatus() == Call.Status.Missed) {
|
if (log.getStatus() == Call.Status.Missed) {
|
||||||
|
@ -187,7 +134,7 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
||||||
private boolean hideHistoryListAndDisplayMessageIfEmpty() {
|
private boolean hideHistoryListAndDisplayMessageIfEmpty() {
|
||||||
removeNotMissedCallsFromLogs();
|
removeNotMissedCallsFromLogs();
|
||||||
if (mLogs.isEmpty()) {
|
if (mLogs.isEmpty()) {
|
||||||
if (onlyDisplayMissedCalls) {
|
if (mOnlyDisplayMissedCalls) {
|
||||||
noMissedCallHistory.setVisibility(View.VISIBLE);
|
noMissedCallHistory.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
noCallHistory.setVisibility(View.VISIBLE);
|
noCallHistory.setVisibility(View.VISIBLE);
|
||||||
|
@ -217,8 +164,10 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
||||||
|
|
||||||
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
|
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
|
||||||
if (!hideHistoryListAndDisplayMessageIfEmpty()) {
|
if (!hideHistoryListAndDisplayMessageIfEmpty()) {
|
||||||
historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
mHistoryAdapter = new CallHistoryAdapter(getActivity().getApplicationContext(), mLogs, this, mSelectionHelper);
|
||||||
historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
|
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) {
|
public void onClick(View v) {
|
||||||
int id = v.getId();
|
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) {
|
if (id == R.id.all_calls) {
|
||||||
allCalls.setEnabled(false);
|
allCalls.setEnabled(false);
|
||||||
allCallsSelected.setVisibility(View.VISIBLE);
|
allCallsSelected.setVisibility(View.VISIBLE);
|
||||||
missedCallsSelected.setVisibility(View.INVISIBLE);
|
missedCallsSelected.setVisibility(View.INVISIBLE);
|
||||||
missedCalls.setEnabled(true);
|
missedCalls.setEnabled(true);
|
||||||
onlyDisplayMissedCalls = false;
|
mOnlyDisplayMissedCalls = false;
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
if (id == R.id.missed_calls) {
|
if (id == R.id.missed_calls) {
|
||||||
|
@ -305,235 +204,42 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
||||||
allCallsSelected.setVisibility(View.INVISIBLE);
|
allCallsSelected.setVisibility(View.INVISIBLE);
|
||||||
missedCallsSelected.setVisibility(View.VISIBLE);
|
missedCallsSelected.setVisibility(View.VISIBLE);
|
||||||
missedCalls.setEnabled(false);
|
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()) {
|
if (!hideHistoryListAndDisplayMessageIfEmpty()) {
|
||||||
historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
// historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||||
historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
|
mHistoryAdapter = new CallHistoryAdapter(mContext, mLogs, this ,mSelectionHelper);
|
||||||
}
|
historyList.setAdapter(mHistoryAdapter);
|
||||||
|
mSelectionHelper.setAdapter(mHistoryAdapter);
|
||||||
if(isEditMode){
|
mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog);
|
||||||
deselectAll.setVisibility(View.GONE);
|
|
||||||
selectAll.setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
|
||||||
if (isEditMode) {
|
if (mHistoryAdapter.isEditionEnabled()) {
|
||||||
CallLog log = mLogs.get(position);
|
CallLog log = mLogs.get(position);
|
||||||
LinphoneManager.getLc().removeCallLog(log);
|
LinphoneManager.getLc().removeCallLog(log);
|
||||||
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
} else {
|
|
||||||
separator.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEditMode) {
|
|
||||||
holder.CallContact.setOnClickListener(null);
|
|
||||||
holder.select.setVisibility(View.VISIBLE);
|
|
||||||
holder.select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
public void onDeleteSelection(Object[] objectsToDelete) {
|
||||||
historyList.setItemChecked(position, b);
|
int size = mHistoryAdapter.getSelectedItemCount();
|
||||||
if(getNbItemsChecked() == getCount()){
|
for(int i=0; i<size; i++) {
|
||||||
deselectAll.setVisibility(View.VISIBLE);
|
CallLog log = (CallLog) objectsToDelete[i];
|
||||||
selectAll.setVisibility(View.GONE);
|
LinphoneManager.getLc().removeCallLog(log);
|
||||||
enabledDeleteButton(true);
|
onResume();
|
||||||
} 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
|
@Override
|
||||||
public void onClick(View v) {
|
public void onItemClicked(int position) {
|
||||||
if (LinphoneActivity.isInstanciated()) {
|
if (mHistoryAdapter.isEditionEnabled()) {
|
||||||
LinphoneActivity.instance().displayHistoryDetail(sipUri, log);
|
mHistoryAdapter.toggleSelection(position);
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
});
|
|
||||||
holder.CallContact.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (LinphoneActivity.isInstanciated()) {
|
if (LinphoneActivity.isInstanciated()) {
|
||||||
CallLog log = mLogs.get(position);
|
CallLog log = mLogs.get(position);
|
||||||
Address address;
|
Address address;
|
||||||
|
@ -542,14 +248,17 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
|
||||||
} else {
|
} else {
|
||||||
address = log.getToAddress();
|
address = log.getToAddress();
|
||||||
}
|
}
|
||||||
if (address != null) {
|
|
||||||
LinphoneActivity.instance().setAddresGoToDialerAndCall(address.asStringUriOnly(), address.getDisplayName(), null);
|
LinphoneActivity.instance().setAddresGoToDialerAndCall(address.asStringUriOnly(), address.getDisplayName(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
return view;
|
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