Update Chat ui
This commit is contained in:
parent
3aae0ef4c3
commit
a1f30e0531
10 changed files with 621 additions and 627 deletions
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:maxLevel="0" android:drawable="@drawable/status_orange" />
|
||||
<item android:maxLevel="0" android:drawable="@drawable/linphone_user" />
|
||||
<item android:maxLevel="1" android:drawable="@drawable/status_green" />
|
||||
<item android:maxLevel="2" android:drawable="@drawable/status_red" />
|
||||
<item android:maxLevel="3" android:drawable="@drawable/status_offline" />
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/bubble"
|
||||
android:background="@drawable/resizable_chat_bubble_incoming"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/resizable_chat_bubble_incoming"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/avatar_layout"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -65,24 +70,50 @@
|
|||
android:layout_width="150dp"
|
||||
android:layout_height="150dp"
|
||||
android:scaleType="center"
|
||||
android:layout_centerInParent="true"
|
||||
android:maxWidth="250dp"
|
||||
android:maxHeight="250dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/download"
|
||||
android:text="@string/download_image"
|
||||
<RelativeLayout
|
||||
android:id="@+id/imageLayout"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:paddingRight="5dp"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="5dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/accept_download"
|
||||
android:text="@string/accept"
|
||||
android:background="@drawable/resizable_assistant_button"
|
||||
style="@style/font8"
|
||||
android:contentDescription="@string/content_description_validate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_below="@id/progress_bar"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/spinner"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="5dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/delete"
|
||||
android:button="@drawable/checkbox"
|
||||
android:contentDescription="@string/content_description_delete"
|
||||
android:paddingRight="5dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,59 +1,91 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/bubble"
|
||||
android:background="@drawable/resizable_chat_bubble_outgoing"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/contact_picture"
|
||||
android:src="@drawable/avatar"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingLeft="10dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="12dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/contact_header"
|
||||
style="@style/font3"
|
||||
android:singleLine="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message"
|
||||
style="@style/font11"
|
||||
android:autoLink="web"
|
||||
android:linksClickable="true"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:background="@drawable/resizable_chat_bubble_outgoing"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:visibility="gone"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="150dp"
|
||||
android:scaleType="center"
|
||||
android:maxWidth="250dp"
|
||||
android:maxHeight="250dp" />
|
||||
android:id="@+id/contact_picture"
|
||||
android:src="@drawable/avatar"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingLeft="10dp"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/spinner"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="20dp"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="5dp"/>
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="12dp">
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/contact_header"
|
||||
style="@style/font3"
|
||||
android:singleLine="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message"
|
||||
style="@style/font11"
|
||||
android:autoLink="web"
|
||||
android:linksClickable="true"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/inprogress"
|
||||
android:visibility="gone"
|
||||
android:paddingRight="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:layout_gravity="top|right"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:visibility="gone"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="150dp"
|
||||
android:scaleType="center"
|
||||
android:layout_centerInParent="true"
|
||||
android:maxWidth="250dp"
|
||||
android:maxHeight="250dp" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/imageLayout"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:paddingRight="5dp"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="5dp"/>
|
||||
<Button
|
||||
android:id="@+id/cancel_upload"
|
||||
android:text="@string/cancel"
|
||||
android:background="@drawable/resizable_confirm_delete_button"
|
||||
style="@style/font15"
|
||||
android:contentDescription="@string/content_description_validate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_below="@id/progress_bar"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/status"
|
||||
|
@ -66,20 +98,20 @@
|
|||
android:layout_height="20dp"
|
||||
android:adjustViewBounds="true" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/inprogress"
|
||||
android:visibility="gone"
|
||||
android:paddingRight="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:layout_gravity="top|right"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/download"
|
||||
android:text="@string/download_image"
|
||||
android:visibility="gone"
|
||||
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/delete"
|
||||
android:button="@drawable/checkbox"
|
||||
android:contentDescription="@string/content_description_delete"
|
||||
android:paddingRight="5dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
|
||||
<Chronometer
|
||||
android:id="@+id/callTimer"
|
||||
android:id="@+id/call_timer"
|
||||
style="@style/font2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
android:scrollHorizontally="true"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
|
|
|
@ -1,96 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- New settings -->
|
||||
<!-- TODO Migrate it in linphonerc -->
|
||||
<bool name="assistant_use_linphone_login_as_first_fragment">false</bool>
|
||||
<string name="default_domain">sip.linphone.org</string>
|
||||
<string name="default_stun">stun.linphone.org</string>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Tutorial settings -->
|
||||
<bool name="show_tutorials_instead_of_app">false</bool> <!-- Be careful ! Setting this to true prevent the app from working ! It will only display tutorial activities -->
|
||||
<string name="wizard_url">https://www.linphone.org/wizard.php</string>
|
||||
|
||||
<!-- Push notification settings -->
|
||||
<bool name="enable_push_id">true</bool>
|
||||
<string name="push_sender_id">622464153529</string>
|
||||
<bool name="hide_camera_settings">false</bool>
|
||||
<bool name="hide_wizard">false</bool>
|
||||
|
||||
|
||||
<string name="default_stun">stun.linphone.org</string>
|
||||
<bool name="override_domain_using_default_one">false</bool> <!-- Replace the domain for outgoing calls by the one above -->
|
||||
<string name="wizard_url">https://www.linphone.org/wizard.php</string>
|
||||
|
||||
<!-- Interface settings -->
|
||||
|
||||
<bool name="hide_camera_settings">false</bool>
|
||||
<bool name="replace_wizard_with_old_interface">false</bool>
|
||||
<bool name="hide_wizard">false</bool>
|
||||
<string name="setup_forced_proxy"></string>
|
||||
<bool name="setup_cancel_move_to_back">false</bool>
|
||||
|
||||
<bool name="setup_account_validation_mandatory">false</bool>
|
||||
<bool name="hide_linphone_accounts_wizard">false</bool>
|
||||
<bool name="hide_generic_accounts_wizard">false</bool>
|
||||
<bool name="hide_remote_provisioning_in_wizard">false</bool>
|
||||
<bool name="allow_cancel_remote_provisioning_login_activity">true</bool>
|
||||
<bool name="hide_accounts">false</bool>
|
||||
<bool name="setup_account_validation_mandatory">false</bool>
|
||||
<bool name="hide_linphone_accounts_wizard">false</bool>
|
||||
<bool name="hide_generic_accounts_wizard">false</bool>
|
||||
<bool name="hide_remote_provisioning_in_wizard">false</bool>
|
||||
<bool name="allow_cancel_remote_provisioning_login_activity">true</bool>
|
||||
<bool name="hide_accounts">false</bool>
|
||||
<bool name="display_account_wizard_at_first_start">true</bool>
|
||||
<bool name="use_linphone_server_ports">true</bool>
|
||||
<bool name="allow_only_phone_numbers_in_wizard">false</bool>
|
||||
|
||||
<bool name="use_android_native_contact_edit_interface">false</bool>
|
||||
<!-- The following settings are only usefull if use_android_native_contact_edit_interface = false -->
|
||||
<bool name="hide_phone_numbers_in_editor">false</bool>
|
||||
<bool name="hide_sip_addresses_in_editor">false</bool>
|
||||
<bool name="forbid_empty_new_contact_in_editor">true</bool>
|
||||
|
||||
<bool name="disable_animations">false</bool>
|
||||
<bool name="show_statusbar_only_on_dialer">true</bool>
|
||||
<bool name="emoticons_in_messages">true</bool>
|
||||
<bool name="only_display_username_if_unknown">true</bool> <!-- Display username for all sip addresses (if not in contact and display name empty) -->
|
||||
<bool name="never_display_sip_addresses">false</bool> <!-- To use only with the above setting set to true -->
|
||||
<bool name="display_messages_time_and_status">true</bool> <!-- Used to show the time of each message arrival -->
|
||||
|
||||
<bool name="enable_linphone_friends">false</bool>
|
||||
<bool name="use_linphone_tag">true</bool>
|
||||
|
||||
<bool name="display_call_stats">true</bool>
|
||||
<bool name="show_current_calls_above_video">false</bool>
|
||||
<bool name="disable_options_in_call">false</bool>
|
||||
|
||||
<!-- Behavior Settings -->
|
||||
<bool name="pre_fill_email_in_wizard">true</bool> <!-- Set the email field of the wizard with one of the gmail account registered on the device -->
|
||||
<bool name="allow_chat_multiline">false</bool>
|
||||
|
||||
<bool name="call_last_log_if_adress_is_empty">true</bool>
|
||||
|
||||
<bool name="allow_ringing_while_early_media">true</bool>
|
||||
<bool name="allow_transfers">true</bool>
|
||||
<bool name="allow_edit_in_dialer">true</bool>
|
||||
<bool name="forbid_self_call">false</bool>
|
||||
|
||||
<bool name="disable_chat">false</bool>
|
||||
<bool name="disable_chat__message_notification">false</bool>
|
||||
<bool name="disable_chat_message_notification">false</bool>
|
||||
|
||||
<bool name="disable_chat_send_file">false</bool>
|
||||
<bool name="use_linphone_chat_storage">true</bool>
|
||||
<bool name="auto_answer_calls">false</bool>
|
||||
<bool name="intercept_outgoing_gsm_calls">false</bool>
|
||||
|
||||
<bool name="allow_transfers">true</bool>
|
||||
|
||||
<bool name="forbid_self_call">false</bool>
|
||||
|
||||
<bool name="disable_animations">false</bool>
|
||||
|
||||
<bool name="automatically_start_intercepted_outgoing_gsm_call">true</bool>
|
||||
<bool name="use_linphonecore_ringing">false</bool>
|
||||
<!-- This settings handle the behavior of the view waiting for the remote provisioning configuration to be done -->
|
||||
<bool name="display_sms_remote_provisioning_activity">false</bool>
|
||||
<bool name="forbid_app_usage_until_remote_provisioning_completed">false</bool>
|
||||
<bool name="display_confirmation_popup_after_first_configuration">false</bool>
|
||||
|
||||
<bool name="hash_images_as_name_before_upload">true</bool>
|
||||
|
||||
<bool name="enable_log_collect">false</bool>
|
||||
<bool name="disable_every_log">false</bool>
|
||||
<bool name="disable_all_security_features_for_markets">false</bool> <!-- Disable TLS/SRTP/ZRTP -->
|
||||
<bool name="disable_all_patented_codecs_for_markets">false</bool> <!-- Disable MPEG4/H264 -->
|
||||
|
||||
<string name="about_bugreport_email">linphone-android@belledonne-communications.com</string>
|
||||
<bool name="use_linphonecore_ringing">false</bool>
|
||||
|
||||
|
||||
<string name="temp_photo_name">linphone-android-photo-temp.jpg</string>
|
||||
<string name="temp_photo_name_with_date">linphone-android-photo-%s.jpg</string>
|
||||
|
||||
|
||||
<bool name="hide_phone_numbers_in_editor">false</bool>
|
||||
<bool name="hide_sip_addresses_in_editor">false</bool>
|
||||
<bool name="setup_cancel_move_to_back">false</bool>
|
||||
<bool name="replace_wizard_with_old_interface">false</bool>
|
||||
|
||||
|
||||
<bool name="enable_call_notification">true</bool>
|
||||
<bool name="kill_service_with_task_manager">true</bool>
|
||||
|
||||
<bool name="hash_images_as_name_before_upload">true</bool>
|
||||
|
||||
<!-- Tutorial settings -->
|
||||
<bool name="show_tutorials_instead_of_app">false</bool> <!-- Be careful ! Setting this to true prevent the app from working ! It will only display tutorial activities -->
|
||||
|
||||
</resources>
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
|
@ -40,11 +40,8 @@ import org.linphone.core.LinphoneChatRoom;
|
|||
import org.linphone.core.LinphoneContent;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneChatMessage.State;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListenerBase;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.PresenceActivityType;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.ui.BubbleChat;
|
||||
|
||||
|
@ -79,21 +76,17 @@ import android.view.ViewGroup;
|
|||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Filter;
|
||||
import android.widget.Filterable;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.SectionIndexer;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
@ -147,7 +140,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
instance = this;
|
||||
View view = inflater.inflate(R.layout.chat, container, false);
|
||||
final View view = inflater.inflate(R.layout.chat, container, false);
|
||||
|
||||
LinphoneManager.addListener(this);
|
||||
// Retain the fragment across configuration changes
|
||||
|
@ -164,10 +157,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
//Initialize UI
|
||||
contactName = (TextView) view.findViewById(R.id.contact_name);
|
||||
//contactPicture = (ImageView) view.findViewById(R.id.contactPicture);
|
||||
messagesList = (ListView) view.findViewById(R.id.chatMessageList);
|
||||
searchContactField = (AutoCompleteTextView) view.findViewById(R.id.searchContactField);
|
||||
|
||||
editList = (RelativeLayout) view.findViewById(R.id.edit_list);
|
||||
textLayout = (RelativeLayout) view.findViewById(R.id.messageLayout);
|
||||
topBar = (RelativeLayout) view.findViewById(R.id.top_bar);
|
||||
|
||||
|
@ -180,8 +173,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
uploadLayout = (RelativeLayout) view.findViewById(R.id.uploadLayout);
|
||||
uploadLayout.setVisibility(View.GONE);
|
||||
|
||||
editList = (RelativeLayout) view.findViewById(R.id.edit_list);
|
||||
|
||||
cancel = (ImageView) view.findViewById(R.id.cancel);
|
||||
cancel.setOnClickListener(this);
|
||||
|
||||
|
@ -207,7 +198,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
edit.setVisibility(View.INVISIBLE);
|
||||
startCall.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
displayChatHeader(displayName, pictureUri);
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (lc != null) {
|
||||
chatRoom = lc.getOrCreateChatRoom(sipUri);
|
||||
|
@ -215,7 +205,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
}
|
||||
|
||||
LinphoneAddress lAddress;
|
||||
LinphoneAddress lAddress = null;
|
||||
try {
|
||||
lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
|
||||
contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
|
||||
|
@ -223,12 +213,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
}
|
||||
|
||||
displayChatHeader(lAddress);
|
||||
|
||||
//Manage multiline
|
||||
message = (EditText) view.findViewById(R.id.message);
|
||||
if (!getResources().getBoolean(R.bool.allow_chat_multiline)) {
|
||||
message.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE);
|
||||
message.setMaxLines(1);
|
||||
}
|
||||
|
||||
sendImage = (ImageView) view.findViewById(R.id.sendPicture);
|
||||
if (!getResources().getBoolean(R.bool.disable_chat_send_file)) {
|
||||
|
@ -260,7 +248,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
if (currentMessageInFileTransferUploadState != null) {
|
||||
uploadLayout.setVisibility(View.GONE);
|
||||
textLayout.setVisibility(View.VISIBLE);
|
||||
progressBar.setProgress(0);
|
||||
|
||||
//progressBar.setProgress(0);
|
||||
currentMessageInFileTransferUploadState.cancelFileTransfer();
|
||||
currentMessageInFileTransferUploadState = null;
|
||||
LinphoneManager.getInstance().setUploadPendingFileMessage(null);
|
||||
|
@ -327,9 +316,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
int heightDiff = getActivity().getWindow().getDecorView().getRootView().getHeight() - (visibleArea.bottom - visibleArea.top);
|
||||
if (heightDiff > 200) {
|
||||
showKeyboardVisibleMode();
|
||||
//showKeyboardVisibleMode();
|
||||
} else {
|
||||
hideKeyboardVisibleMode();
|
||||
//hideKeyboardVisibleMode();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -366,9 +355,29 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
public void refreshHistory() {
|
||||
this.history = null;
|
||||
this.history = chatRoom.getHistory();
|
||||
}
|
||||
|
||||
public void addMessage(LinphoneChatMessage message) {
|
||||
LinphoneChatMessage[] newHist = new LinphoneChatMessage[getCount() +1];
|
||||
for(int i=0; i< getCount(); i++){
|
||||
newHist[i] = this.history[i];
|
||||
}
|
||||
newHist[getCount()] = message;
|
||||
this.history = newHist;
|
||||
}
|
||||
|
||||
public void removeMessage(LinphoneChatMessage message) {
|
||||
LinphoneChatMessage[] newHist = new LinphoneChatMessage[getCount() -1];
|
||||
for(int i=0; i< getCount(); i++){
|
||||
if(this.history[i].getStorageId() != newHist[i].getStorageId())
|
||||
newHist[i] = this.history[i];
|
||||
}
|
||||
newHist[getCount()] = message;
|
||||
this.history = newHist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return history.length;
|
||||
|
@ -394,18 +403,27 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
registerForContextMenu(v);
|
||||
RelativeLayout rlayout = new RelativeLayout(context);
|
||||
|
||||
if(message.isOutgoing()){
|
||||
if(isEditMode) {
|
||||
v.findViewById(R.id.delete).setVisibility(View.VISIBLE);
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
layoutParams.setMargins(100, 10, 10, 10);
|
||||
layoutParams.setMargins(0, 10, 30, 10);
|
||||
v.setLayoutParams(layoutParams);
|
||||
rlayout.addView(v);
|
||||
} else {
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
layoutParams.setMargins(10, 10, 100, 10);
|
||||
v.setLayoutParams(layoutParams);
|
||||
if(message.isOutgoing()){
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
layoutParams.setMargins(100, 10, 10, 10);
|
||||
v.setLayoutParams(layoutParams);
|
||||
} else {
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
layoutParams.setMargins(10, 10, 100, 10);
|
||||
v.setLayoutParams(layoutParams);
|
||||
}
|
||||
rlayout.addView(v);
|
||||
}
|
||||
rlayout.addView(v);
|
||||
return rlayout;
|
||||
}
|
||||
}
|
||||
|
@ -416,15 +434,11 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void displayChatHeader(String displayName, String pictureUri) {
|
||||
private void displayChatHeader(LinphoneAddress address) {
|
||||
if(contact != null) {
|
||||
contactName.setText(contact.getName());
|
||||
} else if (displayName == null && getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) {
|
||||
contactName.setText(LinphoneUtils.getUsernameFromAddress(sipUri));
|
||||
} else if (displayName == null) {
|
||||
contactName.setText(sipUri);
|
||||
} else {
|
||||
contactName.setText(displayName);
|
||||
} else if(address != null){
|
||||
contactName.setText(LinphoneUtils.getAddressDisplayName(address));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,12 +465,12 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
message.setText(draft);
|
||||
}
|
||||
|
||||
LinphoneAddress lAddress;
|
||||
LinphoneAddress lAddress = null;
|
||||
try {
|
||||
lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
|
||||
contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
|
||||
} catch (Exception e){
|
||||
|
||||
Log.w("error");
|
||||
}
|
||||
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
|
@ -466,7 +480,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
chatRoom.markAsRead();
|
||||
}
|
||||
|
||||
displayChatHeader(displayName, pictureUri);
|
||||
displayChatHeader(lAddress);
|
||||
dispayMessageList();
|
||||
}
|
||||
|
||||
|
@ -525,8 +539,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
@Override
|
||||
public void onPause() {
|
||||
message.removeTextChangedListener(textWatcher);
|
||||
removeVirtualKeyboardVisiblityListener();
|
||||
//message.removeTextChangedListener(textWatcher);
|
||||
//removeVirtualKeyboardVisiblityListener();
|
||||
|
||||
|
||||
LinphoneService.instance().removeMessageNotification();
|
||||
|
@ -557,8 +571,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
@SuppressLint("UseSparseArrays")
|
||||
@Override
|
||||
public void onResume() {
|
||||
message.addTextChangedListener(textWatcher);
|
||||
addVirtualKeyboardVisiblityListener();
|
||||
//message.addTextChangedListener(textWatcher);
|
||||
//addVirtualKeyboardVisiblityListener();
|
||||
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (lc != null) {
|
||||
|
@ -566,10 +580,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
if (getResources().getBoolean(R.bool.show_statusbar_only_on_dialer)) {
|
||||
LinphoneActivity.instance().hideStatusBar();
|
||||
}
|
||||
LinphoneActivity.instance().selectMenu(FragmentsAvailable.CHAT);
|
||||
LinphoneActivity.instance().updateChatFragment(this);
|
||||
LinphoneActivity.instance().hideTabBar(false);
|
||||
}
|
||||
|
||||
LinphoneAddress lAddress;
|
||||
|
@ -622,6 +635,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
isEditMode = false;
|
||||
editList.setVisibility(View.GONE);
|
||||
topBar.setVisibility(View.VISIBLE);
|
||||
dispayMessageList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -642,6 +656,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
if (id == R.id.cancel) {
|
||||
Log.w("Cancel");
|
||||
quitEditMode();
|
||||
return;
|
||||
}
|
||||
|
@ -676,6 +691,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
} else if (id == R.id.edit) {
|
||||
topBar.setVisibility(View.GONE);
|
||||
editList.setVisibility(View.VISIBLE);
|
||||
isEditMode = true;
|
||||
dispayMessageList();
|
||||
}
|
||||
else if (id == R.id.new_discussion) {
|
||||
//TODO call sipUri
|
||||
|
@ -690,45 +707,39 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
message.setText("");
|
||||
}
|
||||
|
||||
|
||||
private void displayBubbleChat(LinphoneChatMessage message){
|
||||
adapter.addMessage(message);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void sendTextMessage(String messageToSend) {
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
boolean isNetworkReachable = lc == null ? false : lc.isNetworkReachable();
|
||||
|
||||
//Start new conversation in fast chat
|
||||
if(newChatConversation){
|
||||
String address = searchContactField.getText().toString();
|
||||
if(address != null && !address.equals("")) {
|
||||
if(!address.startsWith("sip:"))
|
||||
address = "sip:" + address;
|
||||
if (!LinphoneUtils.isSipAddress(address)) {
|
||||
if (LinphoneManager.getLc().getDefaultProxyConfig() == null) {
|
||||
Log.w("Error");
|
||||
LinphoneAddress lAddress = LinphoneManager.getLc().getDefaultProxyConfig().normalizeSipUri(address);
|
||||
if(lAddress != null) {
|
||||
chatRoom = lc.getChatRoom(lAddress);
|
||||
if (chatRoom != null && messageToSend != null && messageToSend.length() > 0 && isNetworkReachable) {
|
||||
LinphoneChatMessage message = chatRoom.createLinphoneChatMessage(messageToSend);
|
||||
chatRoom.sendChatMessage(message);
|
||||
message.setListener(LinphoneManager.getInstance());
|
||||
Contact lContact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
|
||||
if (lContact != null)
|
||||
exitNewConversationMode(lContact, lAddress.asStringUriOnly(), null);
|
||||
else
|
||||
exitNewConversationMode(null, lAddress.asStringUriOnly(), lAddress.getUserName());
|
||||
}
|
||||
address = address + "@" + LinphoneManager.getLc().getDefaultProxyConfig().getDomain();
|
||||
}
|
||||
|
||||
LinphoneAddress lAddress;
|
||||
try {
|
||||
lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(address);
|
||||
} catch (LinphoneCoreException e) {
|
||||
Log.e("Cannot display chat",e);
|
||||
return;
|
||||
}
|
||||
|
||||
chatRoom = lc.getOrCreateChatRoom(lAddress.toString());
|
||||
|
||||
if (chatRoom != null && messageToSend != null && messageToSend.length() > 0 && isNetworkReachable) {
|
||||
LinphoneChatMessage message = chatRoom.createLinphoneChatMessage(messageToSend);
|
||||
chatRoom.sendChatMessage(message);
|
||||
message.setListener(LinphoneManager.getInstance());
|
||||
Contact lContact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
|
||||
if(lContact != null)
|
||||
exitNewConversationMode(lContact,lAddress.asStringUriOnly(),null);
|
||||
else
|
||||
exitNewConversationMode(null,lAddress.asStringUriOnly(),lAddress.getUserName());
|
||||
} else {
|
||||
//TODO ERROR MESSAGE
|
||||
LinphoneActivity.instance().displayCustomToast(getString(R.string.error_user_not_found), Toast.LENGTH_LONG);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (chatRoom != null && messageToSend != null && messageToSend.length() > 0 && isNetworkReachable) {
|
||||
LinphoneChatMessage message = chatRoom.createLinphoneChatMessage(messageToSend);
|
||||
chatRoom.sendChatMessage(message);
|
||||
|
@ -825,6 +836,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
if (progressDialog != null && progressDialog.isShowing()) {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
|
||||
Log.w("Post execute");
|
||||
|
||||
mUploadingImageStream = new ByteArrayInputStream(result);
|
||||
|
||||
|
@ -841,6 +854,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
chatRoom.sendChatMessage(message);
|
||||
currentMessageInFileTransferUploadState = message;
|
||||
|
||||
displayBubbleChat(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -967,12 +982,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
@Override
|
||||
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) {
|
||||
//if (state == State.FileTransferDone || state == State.FileTransferError) {
|
||||
// uploadLayout.setVisibility(View.GONE);
|
||||
// textLayout.setVisibility(View.VISIBLE);
|
||||
// progressBar.setProgress(0);
|
||||
// currentMessageInFileTransferUploadState = null;
|
||||
//}
|
||||
Log.w("ICI");
|
||||
if (state == State.FileTransferDone || state == State.FileTransferError) {
|
||||
currentMessageInFileTransferUploadState = null;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
@ -986,21 +999,24 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
@Override
|
||||
public void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total) {
|
||||
progressBar.setProgress(offset * 100 / total);
|
||||
//progressBar.setProgress(offset * 100 / total);
|
||||
}
|
||||
|
||||
class SearchContactsListAdapter extends BaseAdapter implements Filterable {
|
||||
private List<ContactAddress> contacts;
|
||||
//private List<ContactAddress> contacts;
|
||||
private HashMap<Contact, String> contactsList2;
|
||||
private Cursor cursor;
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
SearchContactsListAdapter(List<Contact> contactsList, Cursor c, LayoutInflater inflater) {
|
||||
cursor = c;
|
||||
mInflater = inflater;
|
||||
contacts = new ArrayList<ContactAddress>();
|
||||
contactsList2 = new HashMap<Contact, String>();
|
||||
//contacts = new ArrayList<ContactAddress>();
|
||||
for(Contact con: ContactsManager.getInstance().getAllContacts()){
|
||||
for(String numberOrAddress : con.getNumbersOrAddresses()){
|
||||
contacts.add(new ContactAddress(con,numberOrAddress));
|
||||
contactsList2.put(con,numberOrAddress);
|
||||
//contacts.add(new ContactAddress(con,numberOrAddress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1013,23 +1029,27 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
FilterResults results) {
|
||||
|
||||
if (results.count > 0) {
|
||||
contacts.clear();
|
||||
contacts = (List<ContactAddress>) results.values;
|
||||
//contacts.clear();
|
||||
contactsList2.clear();
|
||||
contactsList2 = ( HashMap<Contact, String>) results.values;
|
||||
//contacts = (List<ContactAddress>) results.values;
|
||||
notifyDataSetChanged();
|
||||
} else {;
|
||||
contacts.clear();
|
||||
contacts = getContactsList();
|
||||
//contacts.clear();
|
||||
contactsList2.clear();
|
||||
contactsList2 = getContactsList();
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
List<ContactAddress> result = new ArrayList<ContactAddress>();
|
||||
//List<ContactAddress> result = new ArrayList<ContactAddress>();
|
||||
HashMap<Contact, String> result = new HashMap<Contact, String>();
|
||||
if(constraint != null) {
|
||||
for (ContactAddress c : contacts) {
|
||||
if (c.mContact.getName().toLowerCase().startsWith(constraint.toString()) || c.mAddress.startsWith(constraint.toString())) {
|
||||
result.add(c);
|
||||
for (HashMap.Entry<Contact, String> entry : contactsList2.entrySet()) {
|
||||
if (entry.getKey().getName().toLowerCase().startsWith(constraint.toString()) || entry.getValue().startsWith(constraint.toString())) {
|
||||
result.put(entry.getKey(),entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1041,36 +1061,29 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
};
|
||||
}
|
||||
|
||||
public List<ContactAddress> getContactsList(){
|
||||
List<ContactAddress> contacts = new ArrayList<ContactAddress>();
|
||||
contacts = new ArrayList<ContactAddress>();
|
||||
public HashMap<Contact, String> getContactsList(){
|
||||
HashMap<Contact, String> contacts = new HashMap<Contact, String>();
|
||||
for(Contact con: ContactsManager.getInstance().getAllContacts()){
|
||||
for(String numberOrAddress : con.getNumbersOrAddresses()){
|
||||
contacts.add(new ContactAddress(con,numberOrAddress));
|
||||
contacts.put(con, numberOrAddress);
|
||||
}
|
||||
}
|
||||
return contacts;
|
||||
}
|
||||
|
||||
class ContactAddress {
|
||||
public Contact mContact;
|
||||
public String mAddress;
|
||||
|
||||
ContactAddress(Contact contact, String address){
|
||||
mContact = contact;
|
||||
mAddress = address;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return contacts.size();
|
||||
return contactsList2.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
if (contacts == null || position >= contacts.size()) {
|
||||
return getContactsList().get(position);
|
||||
public Contact getItem(int position) {
|
||||
if (contactsList2 == null || position >= contactsList2.size()) {
|
||||
contactsList2 = getContactsList();
|
||||
Contact[] s = (Contact[]) contactsList2.keySet().toArray();
|
||||
return s[position];
|
||||
} else {
|
||||
return contacts.get(position);
|
||||
Object[] s = (Object[]) contactsList2.keySet().toArray();
|
||||
return (Contact) s[position];
|
||||
//return contactsList2.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1080,9 +1093,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view = null;
|
||||
ContactAddress contact;
|
||||
Contact contact;
|
||||
do {
|
||||
contact = (ContactAddress) getItem(position);
|
||||
contact = getItem(position);
|
||||
} while (contact == null);
|
||||
|
||||
if (convertView != null) {
|
||||
|
@ -1092,13 +1105,13 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
TextView name = (TextView) view.findViewById(R.id.Contact_name);
|
||||
name.setText(contact.mContact.getName());
|
||||
name.setText(contact.getName());
|
||||
|
||||
final TextView address = (TextView) view.findViewById(R.id.contact_address);
|
||||
address.setText(contact.mAddress);
|
||||
address.setText(contactsList2.get(contact));
|
||||
|
||||
final String a = contact.mAddress;
|
||||
final Contact c = contact.mContact;
|
||||
final String a = contactsList2.get(contact);
|
||||
final Contact c = contact;
|
||||
|
||||
view.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
|
|
|
@ -20,8 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
|
@ -37,6 +35,7 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
|
@ -73,7 +72,6 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
private ImageView edit, selectAll, deselectAll, delete, newDiscussion, contactPicture, cancel;
|
||||
private RelativeLayout editList, topbar;
|
||||
private boolean isEditMode = false;
|
||||
private boolean useLinphoneStorage;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
|
@ -119,7 +117,6 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
|
||||
private void removeChatsConversation(){
|
||||
int size = chatList.getAdapter().getCount();
|
||||
|
||||
for(int i=0; i<size; i++) {
|
||||
if(chatList.isItemChecked(i)){
|
||||
View item = chatList.getAdapter().getView(i, null, null);
|
||||
|
@ -130,6 +127,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
}
|
||||
}
|
||||
}
|
||||
LinphoneActivity.instance().updateMissedChatCount();
|
||||
}
|
||||
|
||||
public void quitEditMode(){
|
||||
|
@ -138,6 +136,29 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
topbar.setVisibility(View.VISIBLE);
|
||||
refresh();
|
||||
}
|
||||
|
||||
public int getNbItemsChecked(){
|
||||
int size = chatList.getAdapter().getCount();
|
||||
int nb = 0;
|
||||
for(int i=0; i<size; i++) {
|
||||
if(chatList.isItemChecked(i)) {
|
||||
nb ++;
|
||||
}
|
||||
}
|
||||
return nb;
|
||||
}
|
||||
|
||||
public void enabledDeleteButton(Boolean enabled){
|
||||
if(enabled){
|
||||
delete.setEnabled(true);
|
||||
delete.setAlpha(1f);
|
||||
} else {
|
||||
if (getNbItemsChecked() == 0){
|
||||
delete.setEnabled(false);
|
||||
delete.setAlpha(0.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hideAndDisplayMessageIfNoChat() {
|
||||
if (mConversations.size() == 0 && mDrafts.size() == 0) {
|
||||
|
@ -148,7 +169,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
noChatHistory.setVisibility(View.GONE);
|
||||
chatList.setVisibility(View.VISIBLE);
|
||||
chatList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
||||
chatList.setAdapter(new ChatListAdapter(useLinphoneStorage));
|
||||
chatList.setAdapter(new ChatListAdapter());
|
||||
edit.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +180,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
mConversations.removeAll(mDrafts);
|
||||
hideAndDisplayMessageIfNoChat();
|
||||
}
|
||||
|
||||
|
||||
private boolean isVersionUsingNewChatStorage() {
|
||||
try {
|
||||
Context context = LinphoneActivity.instance();
|
||||
|
@ -173,13 +194,11 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
//Check if the is the first time we show the chat view since we use liblinphone chat storage
|
||||
useLinphoneStorage = getResources().getBoolean(R.bool.use_linphone_chat_storage);
|
||||
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(LinphoneActivity.instance());
|
||||
boolean updateNeeded = prefs.getBoolean(getString(R.string.pref_first_time_linphone_chat_storage), true);
|
||||
updateNeeded = updateNeeded && !isVersionUsingNewChatStorage();
|
||||
if (useLinphoneStorage && updateNeeded) {
|
||||
if (updateNeeded) {
|
||||
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
|
||||
private ProgressDialog pd;
|
||||
@Override
|
||||
|
@ -214,10 +233,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
if (LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().selectMenu(FragmentsAvailable.CHATLIST);
|
||||
LinphoneActivity.instance().updateChatListFragment(this);
|
||||
|
||||
if (getResources().getBoolean(R.bool.show_statusbar_only_on_dialer)) {
|
||||
LinphoneActivity.instance().hideStatusBar();
|
||||
}
|
||||
LinphoneActivity.instance().hideTabBar(false);
|
||||
}
|
||||
|
||||
refresh();
|
||||
|
@ -252,12 +268,14 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
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;
|
||||
}
|
||||
|
@ -296,6 +314,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
editList.setVisibility(View.VISIBLE);
|
||||
isEditMode = true;
|
||||
hideAndDisplayMessageIfNoChat();
|
||||
enabledDeleteButton(false);
|
||||
}
|
||||
else if (id == R.id.new_discussion) {
|
||||
LinphoneActivity.instance().displayChat(null);
|
||||
|
@ -320,22 +339,12 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
@Override
|
||||
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
|
||||
String sipUri = (String) view.getTag();
|
||||
|
||||
|
||||
if (LinphoneActivity.isInstanciated() && !isEditMode) {
|
||||
LinphoneActivity.instance().displayChat(sipUri);
|
||||
} else if (LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().removeFromChatList(sipUri);
|
||||
LinphoneActivity.instance().removeFromDrafts(sipUri);
|
||||
|
||||
mConversations = LinphoneActivity.instance().getChatList();
|
||||
mDrafts = LinphoneActivity.instance().getDraftChatList();
|
||||
mConversations.removeAll(mDrafts);
|
||||
hideAndDisplayMessageIfNoChat();
|
||||
|
||||
LinphoneActivity.instance().updateMissedChatCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean importAndroidStoredMessagedIntoLibLinphoneStorage() {
|
||||
Log.w("Importing previous messages into new database...");
|
||||
try {
|
||||
|
@ -389,47 +398,12 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
return null;
|
||||
}
|
||||
|
||||
public String timestampToHumanDate(long timestamp) {
|
||||
try {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(timestamp);
|
||||
|
||||
SimpleDateFormat dateFormat;
|
||||
if (isToday(cal)) {
|
||||
dateFormat = new SimpleDateFormat(getResources().getString(R.string.today_date_format));
|
||||
} else {
|
||||
dateFormat = new SimpleDateFormat(getResources().getString(R.string.messages_list_date_format));
|
||||
}
|
||||
|
||||
return dateFormat.format(cal.getTime());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return String.valueOf(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isToday(Calendar cal) {
|
||||
return isSameDay(cal, Calendar.getInstance());
|
||||
}
|
||||
|
||||
private boolean isSameDay(Calendar cal1, Calendar cal2) {
|
||||
if (cal1 == null || cal2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
|
||||
cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
|
||||
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
|
||||
}
|
||||
|
||||
class ChatListAdapter extends BaseAdapter {
|
||||
private boolean useNativeAPI;
|
||||
|
||||
ChatListAdapter(boolean useNativeAPI) {
|
||||
this.useNativeAPI = useNativeAPI;
|
||||
}
|
||||
|
||||
ChatListAdapter() {}
|
||||
|
||||
public int getCount() {
|
||||
return mConversations.size() + mDrafts.size();
|
||||
return mConversations.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
|
@ -447,62 +421,68 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
view = convertView;
|
||||
} else {
|
||||
view = mInflater.inflate(R.layout.chatlist_cell, parent, false);
|
||||
|
||||
}
|
||||
String contact;
|
||||
boolean isDraft = false;
|
||||
if (position >= mDrafts.size()) {
|
||||
contact = mConversations.get(position - mDrafts.size());
|
||||
} else {
|
||||
contact = mDrafts.get(position);
|
||||
isDraft = true;
|
||||
}
|
||||
view.setTag(contact);
|
||||
int unreadMessagesCount = LinphoneActivity.instance().getChatStorage().getUnreadMessageCount(contact);
|
||||
|
||||
String sipUri = mConversations.get(position);
|
||||
view.setTag(sipUri);
|
||||
|
||||
LinphoneAddress address;
|
||||
try {
|
||||
address = LinphoneCoreFactory.instance().createLinphoneAddress(contact);
|
||||
address = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
|
||||
} catch (LinphoneCoreException e) {
|
||||
Log.e("Chat view cannot parse address",e);
|
||||
return view;
|
||||
}
|
||||
Contact lContact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
|
||||
|
||||
Contact contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
|
||||
String message = "";
|
||||
Long time;
|
||||
|
||||
TextView lastMessageView = (TextView) view.findViewById(R.id.lastMessage);
|
||||
LinphoneChatRoom chatRoom = LinphoneManager.getLc().getOrCreateChatRoom(contact);
|
||||
TextView date = (TextView) view.findViewById(R.id.date);
|
||||
TextView displayName = (TextView) view.findViewById(R.id.sipUri);
|
||||
TextView unreadMessages = (TextView) view.findViewById(R.id.unreadMessages);
|
||||
CheckBox select = (CheckBox) view.findViewById(R.id.delete);
|
||||
ImageView contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
|
||||
|
||||
LinphoneChatRoom chatRoom = LinphoneManager.getLc().getChatRoom(address);
|
||||
int unreadMessagesCount = chatRoom.getUnreadMessagesCount();
|
||||
LinphoneChatMessage[] history = chatRoom.getHistory(1);
|
||||
LinphoneChatMessage msg = history[0];
|
||||
TextView date = (TextView) view.findViewById(R.id.date);
|
||||
|
||||
if(msg.getFileTransferInformation() != null || msg.getExternalBodyUrl() != null || msg.getAppData() != null ){
|
||||
lastMessageView.setBackgroundResource(R.drawable.chat_file_message);
|
||||
time = msg.getTime();
|
||||
date.setText(timestampToHumanDate(time));
|
||||
date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format)));
|
||||
lastMessageView.setText("");
|
||||
} else if (msg.getText() != null && msg.getText().length() > 0 ){
|
||||
message = msg.getText();
|
||||
lastMessageView.setBackgroundResource(0);
|
||||
time = msg.getTime();
|
||||
date.setText(timestampToHumanDate(time));
|
||||
date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format)));
|
||||
lastMessageView.setText(message);
|
||||
}
|
||||
|
||||
TextView sipUri = (TextView) view.findViewById(R.id.sipUri);
|
||||
sipUri.setSelected(true); // For animation
|
||||
displayName.setSelected(true); // For animation
|
||||
displayName.setText(contact == null ? LinphoneUtils.getAddressDisplayName(address) : contact.getName());
|
||||
|
||||
if (getResources().getBoolean(R.bool.only_display_username_if_unknown)) {
|
||||
sipUri.setText(lContact == null ? address.getUserName() : lContact.getName());
|
||||
|
||||
if(contact != null){
|
||||
LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
|
||||
}
|
||||
|
||||
if (unreadMessagesCount > 0) {
|
||||
unreadMessages.setVisibility(View.VISIBLE);
|
||||
unreadMessages.setText(String.valueOf(unreadMessagesCount));
|
||||
if(unreadMessagesCount > 99){
|
||||
unreadMessages.setTextSize(12);
|
||||
}
|
||||
displayName.setTypeface(null, Typeface.BOLD);
|
||||
} else {
|
||||
sipUri.setText(lContact == null ? address.asStringUriOnly() : lContact.getName());
|
||||
unreadMessages.setVisibility(View.GONE);
|
||||
displayName.setTypeface(null, Typeface.NORMAL);
|
||||
}
|
||||
|
||||
if (isDraft) {
|
||||
view.findViewById(R.id.draft).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
TextView unreadMessages = (TextView) view.findViewById(R.id.unreadMessages);
|
||||
|
||||
CheckBox select = (CheckBox) view.findViewById(R.id.delete);
|
||||
if (isEditMode) {
|
||||
unreadMessages.setVisibility(View.GONE);
|
||||
select.setVisibility(View.VISIBLE);
|
||||
|
@ -510,23 +490,32 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
chatList.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(chatList.isItemChecked(position)) {
|
||||
select.setChecked(true);
|
||||
enabledDeleteButton(true);
|
||||
} else {
|
||||
select.setChecked(false);
|
||||
}
|
||||
} else {
|
||||
unreadMessages.setVisibility(View.GONE);
|
||||
//delete.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (unreadMessagesCount > 0) {
|
||||
unreadMessages.setVisibility(View.VISIBLE);
|
||||
unreadMessages.setText(String.valueOf(unreadMessagesCount));
|
||||
} else {
|
||||
unreadMessages.setVisibility(View.GONE);
|
||||
if (unreadMessagesCount > 0) {
|
||||
unreadMessages.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
return view;
|
||||
|
|
|
@ -78,7 +78,7 @@ public class ChatStorage {
|
|||
|
||||
private ChatStorage(Context c) {
|
||||
context = c;
|
||||
boolean useLinphoneStorage = c.getResources().getBoolean(R.bool.use_linphone_chat_storage);
|
||||
boolean useLinphoneStorage = false;
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(LinphoneService.instance());
|
||||
boolean updateNeeded = prefs.getBoolean(c.getString(R.string.pref_first_time_linphone_chat_storage), !LinphonePreferences.instance().isFirstLaunch());
|
||||
updateNeeded = updateNeeded && !isVersionUsingNewChatStorage();
|
||||
|
@ -356,71 +356,54 @@ public class ChatStorage {
|
|||
}
|
||||
|
||||
public LinphoneChatMessage getMessage(LinphoneChatRoom chatroom, int id) {
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatMessage[] history = chatroom.getHistory();
|
||||
for (LinphoneChatMessage msg : history) {
|
||||
if (msg.getStorageId() == id) {
|
||||
return msg;
|
||||
}
|
||||
LinphoneChatMessage[] history = chatroom.getHistory();
|
||||
for (LinphoneChatMessage msg : history) {
|
||||
if (msg.getStorageId() == id) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void removeDiscussion(String correspondent) {
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatRoom chatroom = LinphoneManager.getLc().getOrCreateChatRoom(correspondent);
|
||||
chatroom.deleteHistory();
|
||||
} else {
|
||||
db.delete(TABLE_NAME, "remoteContact LIKE \"" + correspondent + "\"", null);
|
||||
}
|
||||
LinphoneChatRoom chatroom = LinphoneManager.getLc().getOrCreateChatRoom(correspondent);
|
||||
chatroom.deleteHistory();
|
||||
}
|
||||
|
||||
public ArrayList<String> getChatList() {
|
||||
ArrayList<String> chatList = new ArrayList<String>();
|
||||
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatRoom[] chats = LinphoneManager.getLc().getChatRooms();
|
||||
List<LinphoneChatRoom> rooms = new ArrayList<LinphoneChatRoom>();
|
||||
LinphoneChatRoom[] chats = LinphoneManager.getLc().getChatRooms();
|
||||
List<LinphoneChatRoom> rooms = new ArrayList<LinphoneChatRoom>();
|
||||
|
||||
for (LinphoneChatRoom chatroom : chats) {
|
||||
if (chatroom.getHistory(1).length > 0) {
|
||||
rooms.add(chatroom);
|
||||
for (LinphoneChatRoom chatroom : chats) {
|
||||
if (chatroom.getHistory(1).length > 0) {
|
||||
Log.w("History non nul " + chatroom.getPeerAddress().asString());
|
||||
rooms.add(chatroom);
|
||||
}
|
||||
}
|
||||
|
||||
if (rooms.size() > 1) {
|
||||
Collections.sort(rooms, new Comparator<LinphoneChatRoom>() {
|
||||
@Override
|
||||
public int compare(LinphoneChatRoom a, LinphoneChatRoom b) {
|
||||
LinphoneChatMessage[] messagesA = a.getHistory(1);
|
||||
LinphoneChatMessage[] messagesB = b.getHistory(1);
|
||||
long atime = messagesA[0].getTime();
|
||||
long btime = messagesB[0].getTime();
|
||||
|
||||
if (atime > btime)
|
||||
return -1;
|
||||
else if (btime > atime)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (rooms.size() > 1) {
|
||||
Collections.sort(rooms, new Comparator<LinphoneChatRoom>() {
|
||||
@Override
|
||||
public int compare(LinphoneChatRoom a, LinphoneChatRoom b) {
|
||||
LinphoneChatMessage[] messagesA = a.getHistory(1);
|
||||
LinphoneChatMessage[] messagesB = b.getHistory(1);
|
||||
long atime = messagesA[0].getTime();
|
||||
long btime = messagesB[0].getTime();
|
||||
|
||||
if (atime > btime)
|
||||
return -1;
|
||||
else if (btime > atime)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (LinphoneChatRoom chatroom : rooms) {
|
||||
chatList.add(chatroom.getPeerAddress().asStringUriOnly());
|
||||
}
|
||||
} else {
|
||||
Cursor c = db.query(TABLE_NAME, null, null, null, "remoteContact", null, "id DESC");
|
||||
while (c != null && c.moveToNext()) {
|
||||
try {
|
||||
String remoteContact = c.getString(c.getColumnIndex("remoteContact"));
|
||||
chatList.add(remoteContact);
|
||||
} catch (IllegalStateException ise) {
|
||||
}
|
||||
}
|
||||
c.close();
|
||||
for (LinphoneChatRoom chatroom : rooms) {
|
||||
chatList.add(chatroom.getPeerAddress().asStringUriOnly());
|
||||
}
|
||||
|
||||
return chatList;
|
||||
|
@ -454,53 +437,6 @@ public class ChatStorage {
|
|||
}
|
||||
}
|
||||
|
||||
public int getUnreadMessageCount() {
|
||||
int count;
|
||||
if (!useNativeAPI) {
|
||||
Cursor c = db.query(TABLE_NAME, null, "read LIKE " + NOT_READ, null, null, null, null);
|
||||
count = c.getCount();
|
||||
c.close();
|
||||
} else {
|
||||
count = 0;
|
||||
LinphoneChatRoom[] chats = LinphoneManager.getLc().getChatRooms();
|
||||
for (LinphoneChatRoom chatroom : chats) {
|
||||
count += chatroom.getUnreadMessagesCount();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getUnreadMessageCount(String contact) {
|
||||
int count;
|
||||
if (!useNativeAPI) {
|
||||
Cursor c = db.query(TABLE_NAME, null, "remoteContact LIKE \"" + contact + "\" AND read LIKE " + NOT_READ, null, null, null, null);
|
||||
count = c.getCount();
|
||||
c.close();
|
||||
} else {
|
||||
LinphoneChatRoom chatroom = LinphoneManager.getLc().getOrCreateChatRoom(contact);
|
||||
count = chatroom.getUnreadMessagesCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public byte[] getRawImageFromMessage(int id) {
|
||||
if (useNativeAPI) {
|
||||
//Handled before this point
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] columns = { "image" };
|
||||
Cursor c = db.query(TABLE_NAME, columns, "id LIKE " + id + "", null, null, null, null);
|
||||
|
||||
if (c.moveToFirst()) {
|
||||
byte[] rawImage = c.getBlob(c.getColumnIndex("image"));
|
||||
c.close();
|
||||
return (rawImage == null || rawImage.length == 0) ? null : rawImage;
|
||||
}
|
||||
|
||||
c.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
class ChatHelper extends SQLiteOpenHelper {
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ import android.widget.Button;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
|
@ -79,10 +79,10 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
private LinphoneChatMessage nativeMessage;
|
||||
private Context mContext;
|
||||
private static final int SIZE_MAX = 512;
|
||||
private ProgressBar spinner, inprogress;
|
||||
private ProgressBar progressBar, inprogress;
|
||||
private Bitmap defaultBitmap;
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
public BubbleChat(final Context context, LinphoneChatMessage message, Contact c) {
|
||||
if (message == null) {
|
||||
return;
|
||||
|
@ -97,80 +97,103 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
}
|
||||
|
||||
defaultBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_picture_over);
|
||||
inprogress = (ProgressBar) view.findViewById(R.id.inprogress);
|
||||
|
||||
view.setId(message.getStorageId());
|
||||
|
||||
spinner = (ProgressBar) view.findViewById(R.id.spinner);
|
||||
progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
|
||||
|
||||
String externalBodyUrl = message.getExternalBodyUrl();
|
||||
LinphoneContent fileTransferContent = message.getFileTransferInformation();
|
||||
LinphoneChatMessage.State status = message.getStatus();
|
||||
statusView = (ImageView) view.findViewById(R.id.status);
|
||||
|
||||
if (statusView != null) {
|
||||
if (status == LinphoneChatMessage.State.Delivered) {
|
||||
statusView.setVisibility(View.INVISIBLE);
|
||||
inprogress.setVisibility(View.GONE);
|
||||
} else if (status == LinphoneChatMessage.State.NotDelivered) {
|
||||
statusView.setVisibility(View.VISIBLE);
|
||||
statusView.setImageResource(R.drawable.chat_message_not_delivered);
|
||||
} else {
|
||||
statusView.setVisibility(View.GONE);
|
||||
inprogress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
String externalBodyUrl = message.getExternalBodyUrl();
|
||||
LinphoneContent fileTransferContent = message.getFileTransferInformation();
|
||||
|
||||
if(LinphoneManager.getInstance().getMessageUploadPending() != null){
|
||||
spinner.setVisibility(View.VISIBLE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
nativeMessage.setListener(LinphoneManager.getInstance());
|
||||
}
|
||||
|
||||
if (externalBodyUrl != null || fileTransferContent != null) {
|
||||
Button download = (Button) view.findViewById(R.id.download);
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.image);
|
||||
if (externalBodyUrl != null || fileTransferContent != null ) {
|
||||
String appData = message.getAppData();
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.image);
|
||||
|
||||
String appData = message.getAppData();
|
||||
if(appData != null && !LinphoneManager.getInstance().isMessagePending(nativeMessage) &&
|
||||
!nativeMessage.isOutgoing() && appData.contains(context.getString(R.string.temp_photo_name_with_date).split("%s")[0])){
|
||||
appData = null;
|
||||
}
|
||||
if(nativeMessage.isOutgoing() && appData != null){
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
loadBitmap(appData, imageView);
|
||||
|
||||
if (appData == null ){
|
||||
LinphoneManager.addListener(this);
|
||||
download.setVisibility(View.VISIBLE);
|
||||
download.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
v.setEnabled(false);
|
||||
v.setVisibility(View.GONE);
|
||||
spinner.setVisibility(View.VISIBLE);
|
||||
String filename = context.getString(R.string.temp_photo_name_with_date).replace("%s", String.valueOf(System.currentTimeMillis()));
|
||||
File file = new File(Environment.getExternalStorageDirectory(), filename);
|
||||
nativeMessage.setAppData(filename);
|
||||
LinphoneManager.getInstance().addDownloadMessagePending(nativeMessage);
|
||||
nativeMessage.setListener(LinphoneManager.getInstance());
|
||||
nativeMessage.setFileTransferFilepath(file.getPath());
|
||||
nativeMessage.downloadFile();
|
||||
}
|
||||
});
|
||||
RelativeLayout imageLayout = (RelativeLayout) view.findViewById(R.id.imageLayout);
|
||||
if(LinphoneManager.getInstance().getMessageUploadPending() != null && LinphoneManager.getInstance().getMessageUploadPending().getStorageId() == nativeMessage.getStorageId()){
|
||||
inprogress.setVisibility(View.INVISIBLE);
|
||||
imageLayout.setVisibility(View.VISIBLE);
|
||||
nativeMessage.setListener(LinphoneManager.getInstance());
|
||||
}
|
||||
} else {
|
||||
if (LinphoneManager.getInstance().isMessagePending(nativeMessage)) {
|
||||
if (appData != null && !LinphoneManager.getInstance().isMessagePending(nativeMessage) &&
|
||||
appData.contains(context.getString(R.string.temp_photo_name_with_date).split("%s")[0])) {
|
||||
appData = null;
|
||||
}
|
||||
|
||||
RelativeLayout imageLayout = (RelativeLayout) view.findViewById(R.id.imageLayout);
|
||||
Button acceptDownload = (Button) view.findViewById(R.id.accept_download);
|
||||
|
||||
if (appData == null) {
|
||||
LinphoneManager.addListener(this);
|
||||
download.setEnabled(false);
|
||||
ProgressBar spinner = (ProgressBar) view.findViewById(R.id.spinner);
|
||||
spinner.setVisibility(View.VISIBLE);
|
||||
download.setVisibility(View.GONE);
|
||||
imageLayout.setVisibility(View.VISIBLE);
|
||||
acceptDownload.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
v.setEnabled(false);
|
||||
String filename = context.getString(R.string.temp_photo_name_with_date).replace("%s", String.valueOf(System.currentTimeMillis()));
|
||||
File file = new File(Environment.getExternalStorageDirectory(), filename);
|
||||
nativeMessage.setAppData(filename);
|
||||
LinphoneManager.getInstance().addDownloadMessagePending(nativeMessage);
|
||||
nativeMessage.setListener(LinphoneManager.getInstance());
|
||||
nativeMessage.setFileTransferFilepath(file.getPath());
|
||||
nativeMessage.downloadFile();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
LinphoneManager.removeListener(this);
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
download.setVisibility(View.GONE);
|
||||
loadBitmap(appData, imageView);
|
||||
if (LinphoneManager.getInstance().isMessagePending(nativeMessage)) {
|
||||
LinphoneManager.addListener(this);
|
||||
acceptDownload.setEnabled(false);
|
||||
imageLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
LinphoneManager.removeListener(this);
|
||||
imageLayout.setVisibility(View.GONE);
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
loadBitmap(appData, imageView);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TextView msgView = (TextView) view.findViewById(R.id.message);
|
||||
if (msgView != null) {
|
||||
Spanned text = null;
|
||||
String msg = message.getText();
|
||||
if (msg != null) {
|
||||
if (context.getResources().getBoolean(R.bool.emoticons_in_messages)) {
|
||||
text = getSmiledText(context, getTextWithHttpLinks(msg));
|
||||
} else {
|
||||
text = getTextWithHttpLinks(msg);
|
||||
}
|
||||
msgView.setText(text);
|
||||
msgView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
msgView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextView contact = (TextView) view.findViewById(R.id.contact_header);
|
||||
} else {
|
||||
TextView msgView = (TextView) view.findViewById(R.id.message);
|
||||
if (msgView != null) {
|
||||
Spanned text = null;
|
||||
String msg = message.getText();
|
||||
if (msg != null) {
|
||||
text = getSmiledText(context, getTextWithHttpLinks(msg));
|
||||
msgView.setText(text);
|
||||
msgView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
msgView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextView contact = (TextView) view.findViewById(R.id.contact_header);
|
||||
|
||||
|
||||
|
||||
|
@ -189,60 +212,44 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
|
||||
contact.setText(timestampToHumanDate(context, message.getTime()) + " - " + displayName);
|
||||
|
||||
LinphoneChatMessage.State status = message.getStatus();
|
||||
statusView = (ImageView) view.findViewById(R.id.status);
|
||||
inprogress = (ProgressBar) view.findViewById(R.id.inprogress);
|
||||
if (statusView != null) {
|
||||
if (status == LinphoneChatMessage.State.Delivered) {
|
||||
statusView.setVisibility(View.INVISIBLE);
|
||||
inprogress.setVisibility(View.GONE);
|
||||
} else if (status == LinphoneChatMessage.State.NotDelivered) {
|
||||
statusView.setVisibility(View.VISIBLE);
|
||||
statusView.setImageResource(R.drawable.chat_message_not_delivered);
|
||||
} else {
|
||||
statusView.setVisibility(View.GONE);
|
||||
inprogress.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public View getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
private String timestampToHumanDate(Context context, long timestamp) {
|
||||
try {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(timestamp);
|
||||
|
||||
|
||||
SimpleDateFormat dateFormat;
|
||||
if (isToday(cal)) {
|
||||
dateFormat = new SimpleDateFormat(context.getResources().getString(R.string.today_date_format));
|
||||
} else {
|
||||
dateFormat = new SimpleDateFormat(context.getResources().getString(R.string.messages_date_format));
|
||||
}
|
||||
|
||||
|
||||
return dateFormat.format(cal.getTime());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return String.valueOf(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isToday(Calendar cal) {
|
||||
return isSameDay(cal, Calendar.getInstance());
|
||||
}
|
||||
|
||||
return isSameDay(cal, Calendar.getInstance());
|
||||
}
|
||||
|
||||
private boolean isSameDay(Calendar cal1, Calendar cal2) {
|
||||
if (cal1 == null || cal2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
|
||||
cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
|
||||
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
public static Spannable getSmiledText(Context context, Spanned spanned) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(spanned);
|
||||
String text = spanned.toString();
|
||||
|
@ -256,10 +263,10 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
indexOf = text.indexOf(key, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
public static Spanned getTextWithHttpLinks(String text) {
|
||||
if (text.contains("<")) {
|
||||
text = text.replace("<", "<");
|
||||
|
@ -281,10 +288,10 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
String linkWithoutScheme = link.replace("https://", "");
|
||||
text = text.replaceFirst(link, "<a href=\"" + link + "\">" + linkWithoutScheme + "</a>");
|
||||
}
|
||||
|
||||
|
||||
return Html.fromHtml(text);
|
||||
}
|
||||
|
||||
|
||||
public String getTextMessage() {
|
||||
return nativeMessage.getText();
|
||||
}
|
||||
|
@ -292,15 +299,15 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
public State getStatus() {
|
||||
return nativeMessage.getStatus();
|
||||
}
|
||||
|
||||
|
||||
public LinphoneChatMessage getNativeMessageObject() {
|
||||
return nativeMessage;
|
||||
}
|
||||
|
||||
|
||||
public int getId() {
|
||||
return nativeMessage.getStorageId();
|
||||
}
|
||||
|
||||
|
||||
public void loadBitmap(String path, ImageView imageView) {
|
||||
if (cancelPotentialWork(path, imageView)) {
|
||||
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
|
||||
|
@ -308,110 +315,110 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
imageView.setImageDrawable(asyncBitmap);
|
||||
task.execute(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
|
||||
private final WeakReference<ImageView> imageViewReference;
|
||||
public String path;
|
||||
private final WeakReference<ImageView> imageViewReference;
|
||||
public String path;
|
||||
|
||||
public BitmapWorkerTask(ImageView imageView) {
|
||||
path = null;
|
||||
// Use a WeakReference to ensure the ImageView can be garbage collected
|
||||
imageViewReference = new WeakReference<ImageView>(imageView);
|
||||
}
|
||||
public BitmapWorkerTask(ImageView imageView) {
|
||||
path = null;
|
||||
// Use a WeakReference to ensure the ImageView can be garbage collected
|
||||
imageViewReference = new WeakReference<ImageView>(imageView);
|
||||
}
|
||||
|
||||
// Decode image in background.
|
||||
@Override
|
||||
protected Bitmap doInBackground(String... params) {
|
||||
path = params[0];
|
||||
Bitmap bm = null;
|
||||
|
||||
if (path.startsWith("content")) {
|
||||
try {
|
||||
bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), Uri.parse(path));
|
||||
// Decode image in background.
|
||||
@Override
|
||||
protected Bitmap doInBackground(String... params) {
|
||||
path = params[0];
|
||||
Bitmap bm = null;
|
||||
|
||||
if (path.startsWith("content")) {
|
||||
try {
|
||||
bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), Uri.parse(path));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(e);
|
||||
} catch (IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
} else {
|
||||
bm = BitmapFactory.decodeFile(path);
|
||||
path = "file://" + path;
|
||||
}
|
||||
|
||||
if (bm != null) {
|
||||
} else {
|
||||
bm = BitmapFactory.decodeFile(path);
|
||||
path = "file://" + path;
|
||||
}
|
||||
|
||||
if (bm != null) {
|
||||
bm = ThumbnailUtils.extractThumbnail(bm, SIZE_MAX, SIZE_MAX);
|
||||
}
|
||||
return bm;
|
||||
}
|
||||
}
|
||||
return bm;
|
||||
}
|
||||
|
||||
// Once complete, see if ImageView is still around and set bitmap.
|
||||
@Override
|
||||
protected void onPostExecute(Bitmap bitmap) {
|
||||
if (isCancelled()) {
|
||||
bitmap = null;
|
||||
}
|
||||
// Once complete, see if ImageView is still around and set bitmap.
|
||||
@Override
|
||||
protected void onPostExecute(Bitmap bitmap) {
|
||||
if (isCancelled()) {
|
||||
bitmap = null;
|
||||
}
|
||||
|
||||
if (imageViewReference != null && bitmap != null) {
|
||||
final ImageView imageView = imageViewReference.get();
|
||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||
if (this == bitmapWorkerTask && imageView != null) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
if (imageViewReference != null && bitmap != null) {
|
||||
final ImageView imageView = imageViewReference.get();
|
||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||
if (this == bitmapWorkerTask && imageView != null) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
|
||||
imageView.setTag(path);
|
||||
imageView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.parse((String)v.getTag()), "image/*");
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
imageView.setTag(path);
|
||||
imageView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.parse((String)v.getTag()), "image/*");
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class AsyncBitmap extends BitmapDrawable {
|
||||
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
|
||||
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
|
||||
|
||||
public AsyncBitmap(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
|
||||
super(res, bitmap);
|
||||
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
|
||||
}
|
||||
public AsyncBitmap(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
|
||||
super(res, bitmap);
|
||||
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
|
||||
}
|
||||
|
||||
public BitmapWorkerTask getBitmapWorkerTask() {
|
||||
return bitmapWorkerTaskReference.get();
|
||||
}
|
||||
public BitmapWorkerTask getBitmapWorkerTask() {
|
||||
return bitmapWorkerTaskReference.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean cancelPotentialWork(String path, ImageView imageView) {
|
||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||
|
||||
if (bitmapWorkerTask != null) {
|
||||
final String bitmapData = bitmapWorkerTask.path;
|
||||
// If bitmapData is not yet set or it differs from the new data
|
||||
if (bitmapData == null || bitmapData != path) {
|
||||
// Cancel previous task
|
||||
bitmapWorkerTask.cancel(true);
|
||||
} else {
|
||||
// The same work is already in progress
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// No task associated with the ImageView, or an existing task was cancelled
|
||||
return true;
|
||||
if (bitmapWorkerTask != null) {
|
||||
final String bitmapData = bitmapWorkerTask.path;
|
||||
// If bitmapData is not yet set or it differs from the new data
|
||||
if (bitmapData == null || bitmapData != path) {
|
||||
// Cancel previous task
|
||||
bitmapWorkerTask.cancel(true);
|
||||
} else {
|
||||
// The same work is already in progress
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// No task associated with the ImageView, or an existing task was cancelled
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
||||
if (imageView != null) {
|
||||
final Drawable drawable = imageView.getDrawable();
|
||||
if (drawable instanceof AsyncBitmap) {
|
||||
final AsyncBitmap asyncDrawable = (AsyncBitmap) drawable;
|
||||
return asyncDrawable.getBitmapWorkerTask();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
if (imageView != null) {
|
||||
final Drawable drawable = imageView.getDrawable();
|
||||
if (drawable instanceof AsyncBitmap) {
|
||||
final AsyncBitmap asyncDrawable = (AsyncBitmap) drawable;
|
||||
return asyncDrawable.getBitmapWorkerTask();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -429,6 +436,6 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
@Override
|
||||
public void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total) {
|
||||
if(nativeMessage.getStorageId() == msg.getStorageId())
|
||||
spinner.setProgress(offset * 100 / total);
|
||||
progressBar.setProgress(offset * 100 / total);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue