package com.steps.geosms.conversationsList;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.LoaderManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.Telephony;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.ioane.sharvadze.geosms.R;
import com.melnykov.fab.FloatingActionButton;
import com.nispok.snackbar.Snackbar;
import com.nispok.snackbar.SnackbarManager;
import com.nispok.snackbar.listeners.ActionClickListener;
import com.nispok.snackbar.listeners.EventListener;
import com.steps.geosms.conversation.ConversationActivity;
import com.steps.geosms.newConversation.NewConversationActivity;
import com.steps.geosms.notifications.SmsManagerService;
import com.steps.geosms.objects.Contact;
import com.steps.geosms.objects.Conversation;
import com.steps.geosms.utils.Constants;
import com.steps.geosms.utils.MyActivity;
import com.steps.geosms.utils.Utils;
import java.util.ArrayList;
import java.util.List;
public class ConversationsListActivity extends MyActivity implements AdapterView.OnItemClickListener,
LoaderManager.LoaderCallbacks<ArrayList<Conversation>> {
private final String TAG = ConversationsListActivity.class.getSimpleName();
private ArrayAdapter<Conversation> listAdapter;
private ListView mListView;
private FloatingActionButton fab;
/**
* This int is just to
*/
private final int DEFAULT_SMS_REQUEST = 14;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(R.string.main_title);
setContentView(R.layout.activity_conversations_list);
ArrayList<Conversation> conversations = Utils.loadConversationsFromCache(getBaseContext());
if(conversations == null) conversations = new ArrayList<>();
listAdapter = new ConversationsListAdapter(getBaseContext(),
R.layout.conversation_item, conversations);
mListView = (ListView) findViewById(R.id.conversations_list_view);
mListView.setAdapter(listAdapter);
// Listen to clicks
mListView.setOnItemClickListener(this);
// listen for conversation updates
initMultiChoiceListView();
fab = (FloatingActionButton) findViewById(R.id.fab);
getLoaderManager().initLoader(0, null, this);
}
@Override
protected void onResume() {
super.onResume();
new Thread(new Runnable() {
@Override
public void run() {
SmsManagerService.dismissSummaryNotifications(ConversationsListActivity.this);
}
}).start();
// if it's default app , it changes layout.
defaultAppResolve();
}
private void defaultAppResolve() {
if (!Utils.isDefaultSmsApp(getApplicationContext())) {
Log.d(TAG, "not default app");
// App is not default.
// Show the "not currently set as the default SMS app" interface
View viewGroup = findViewById(R.id.not_default_app);
viewGroup.setVisibility(View.VISIBLE);
// Set up a button that allows the user to change the default SMS app
setUpDefaultAppResolver();
} else {
// App is the default.
// Hide the "not currently set as the default SMS app" interface
View viewGroup = findViewById(R.id.not_default_app);
viewGroup.setVisibility(View.GONE);
}
}
@TargetApi(19)
private void setUpDefaultAppResolver(){
Button button = (Button) findViewById(R.id.change_default_app);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName());
startActivityForResult(intent, DEFAULT_SMS_REQUEST);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case DEFAULT_SMS_REQUEST:
int msgId;
if (resultCode == Activity.RESULT_OK) {
View viewGroup = findViewById(R.id.not_default_app);
viewGroup.setVisibility(View.GONE);
msgId = R.string.sms_default_success;
} else {
msgId = R.string.sms_default_fail;
}
Toast.makeText(getBaseContext(), msgId, Toast.LENGTH_SHORT).show();
}
}
@Override
public Loader<ArrayList<Conversation>> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader with no arguments, so it is simple.
return new ConversationListLoader(getBaseContext());
}
@Override
public void onLoadFinished(Loader<ArrayList<Conversation>> loader, ArrayList<Conversation> data) {
// Set the new data in the adapter.
listAdapter.clear();
listAdapter.addAll(data);
listAdapter.notifyDataSetChanged();
Utils.cacheConversations(getBaseContext(), data);
}
@Override
public void onLoaderReset(Loader<ArrayList<Conversation>> loader) {
// Clear the data in the adapter.
listAdapter.clear();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Conversation conversation = listAdapter.getItem(position);
Intent i = new Intent(ConversationsListActivity.this, ConversationActivity.class);
i.putExtra(Constants.CONTACT_DATA, conversation.getContacts());
i.putExtra(Constants.THREAD_ID, conversation.getId());
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
//overridePendingTransition(R.animator.abc_slide_in_left, R.anim.abc_fade_out);
}
/**
* When user clicks new_conversation button we redirect
* him to new conversation activity.
*
* @param view Button that was clicked.
*/
public void newConversation(View view){
Intent i = new Intent(ConversationsListActivity.this, NewConversationActivity.class);
startActivity(i);
}
private void initMultiChoiceListView() {
mListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
final String text = getResources().getString(R.string.selected);
mode.setTitle(String.format("%s %d" , text, mListView.getCheckedItemCount()));
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.conversations_list_cab, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete:
AlertDialog.Builder builder = new AlertDialog.Builder(ConversationsListActivity.this);
SparseBooleanArray checkedItemPositions = mListView.getCheckedItemPositions();
final List<Integer> checkedIds = new ArrayList<>(checkedItemPositions.size());
for (int i = 0; i < checkedItemPositions.size(); i++)
if (checkedItemPositions.get(checkedItemPositions.keyAt(i)))
checkedIds.add(checkedItemPositions.keyAt(i));
builder.setTitle(R.string.warning);
builder.setMessage(checkedIds.size() == 1 ? R.string.delete_warning_msg_single :
R.string.delete_warning_msg_plural);
builder.setPositiveButton("YES", new DatePickerDialog.OnClickListener() {
public void onClick(DialogInterface dialog, final int which) {
ArrayList<Conversation> deleteList = new ArrayList<>(checkedIds.size());
for (long id : checkedIds) {
Conversation toDelete = listAdapter.getItem((int) id);
deleteList.add(toDelete);
}
// than delete conversations
for(Conversation toDelete : deleteList){
listAdapter.remove(toDelete);
}
listAdapter.notifyDataSetChanged();
new AsyncUndoDelete(deleteList, checkedIds).execute();
mode.finish();
dialog.dismiss();
}
});
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mode.finish();
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
public void onContactImageClick(View v) {
Contact contact = (Contact) v.getTag(R.string.contact);
if (contact == null) {
Log.i(TAG, "contact null");
} else {
Intent intent;
if (TextUtils.isEmpty(contact.getName())) {
intent = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT, ContactsContract.Contacts.CONTENT_URI);
intent.setData(Uri.fromParts("tel", contact.getAddress(), null));
intent.putExtra(ContactsContract.Intents.Insert.NAME, contact.getName());
intent.putExtra(ContactsContract.Intents.Insert.PHONE, contact.getAddress());
intent.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE,
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
// TODO need any flags?
//intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(intent);
} else {
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contact.getId()));
ContactsContract.QuickContact.showQuickContact(this, findViewById(R.id.quick_contact), uri,
ContactsContract.QuickContact.MODE_MEDIUM, null);
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_conversation_list, menu);
return true;
}
private class AsyncUndoDelete extends AsyncTask<Void,Void,Boolean>{
ArrayList<Conversation> mToDeleteList;
List<Integer> mIndexes;
/**
* @param toDeleteList list to delete if not undo.
*/
public AsyncUndoDelete(ArrayList<Conversation> toDeleteList, List<Integer> indexes){
mToDeleteList = toDeleteList;
mIndexes = indexes;
}
private void restore(){
for(int i=0;i<mIndexes.size();i++){
listAdapter.insert(mToDeleteList.get(i),mIndexes.get(i));
}
listAdapter.notifyDataSetChanged();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
String text = getResources().getString(R.string.conversations_deleted);
Snackbar snackbar = Snackbar.with(getApplicationContext())
.eventListener(new EventListener() {
@Override
public void onShow(Snackbar snackbar) {
fab.animate().translationYBy(-snackbar.getHeight());
}
@Override
public void onShowByReplace(Snackbar snackbar) {}
@Override
public void onShown(Snackbar snackbar) {}
@Override
public void onDismiss(Snackbar snackbar) {}
@Override
public void onDismissByReplace(Snackbar snackbar) {}
@Override
public void onDismissed(Snackbar snackbar) {
fab.animate().translationYBy(snackbar.getHeight());
}
})
.text(String.format("%d %s", mToDeleteList.size(), text))
.actionLabel(R.string.undo).actionColorResource(R.color.themeAccent)
.duration(Snackbar.SnackbarDuration.LENGTH_LONG)
.actionListener(new ActionClickListener() {
@Override
public void onActionClicked(Snackbar snackbar) {
cancel(false);
restore();
}
});
SnackbarManager.show(snackbar, ConversationsListActivity.this);
}
@Override
protected Boolean doInBackground(Void... params) {
try {
Thread.sleep(3500);
if(isCancelled())
return false;
} catch (InterruptedException e) {
return false;
}
for(Conversation toDelete: mToDeleteList){
getContentResolver().delete(
Uri.parse("content://mms-sms/conversations"),
"thread_id=?", new String[]{Long.toString(toDelete.getId())});
}
return true;
}
}
}