package com.quickblox.sample.chat.ui.activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.view.ActionMode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.orangegangsters.github.swipyrefreshlayout.library.SwipyRefreshLayout;
import com.orangegangsters.github.swipyrefreshlayout.library.SwipyRefreshLayoutDirection;
import com.quickblox.chat.QBChatService;
import com.quickblox.chat.QBIncomingMessagesManager;
import com.quickblox.chat.QBSystemMessagesManager;
import com.quickblox.chat.exception.QBChatException;
import com.quickblox.chat.listeners.QBChatDialogMessageListener;
import com.quickblox.chat.listeners.QBSystemMessageListener;
import com.quickblox.chat.model.QBChatDialog;
import com.quickblox.chat.model.QBChatMessage;
import com.quickblox.core.QBEntityCallback;
import com.quickblox.core.exception.QBResponseException;
import com.quickblox.core.request.QBRequestGetBuilder;
import com.quickblox.messages.services.SubscribeService;
import com.quickblox.sample.chat.R;
import com.quickblox.sample.chat.managers.DialogsManager;
import com.quickblox.sample.chat.ui.adapter.DialogsAdapter;
import com.quickblox.sample.chat.utils.chat.ChatHelper;
import com.quickblox.sample.chat.utils.qb.QbChatDialogMessageListenerImp;
import com.quickblox.sample.chat.utils.qb.QbDialogHolder;
import com.quickblox.sample.chat.utils.qb.callback.QbEntityCallbackImpl;
import com.quickblox.sample.core.gcm.GooglePlayServicesHelper;
import com.quickblox.sample.core.ui.dialog.ProgressDialogFragment;
import com.quickblox.sample.core.utils.SharedPrefsHelper;
import com.quickblox.sample.core.utils.constant.GcmConsts;
import com.quickblox.users.model.QBUser;
import java.util.ArrayList;
import java.util.Collection;
public class DialogsActivity extends BaseActivity implements DialogsManager.ManagingDialogsCallbacks {
private static final String TAG = DialogsActivity.class.getSimpleName();
private static final int REQUEST_SELECT_PEOPLE = 174;
private static final int REQUEST_DIALOG_ID_FOR_UPDATE = 165;
private ProgressBar progressBar;
private FloatingActionButton fab;
private ActionMode currentActionMode;
private SwipyRefreshLayout setOnRefreshListener;
private QBRequestGetBuilder requestBuilder;
private Menu menu;
private int skipRecords = 0;
private boolean isProcessingResultInProgress;
private BroadcastReceiver pushBroadcastReceiver;
private GooglePlayServicesHelper googlePlayServicesHelper;
private DialogsAdapter dialogsAdapter;
private QBChatDialogMessageListener allDialogsMessagesListener;
private SystemMessagesListener systemMessagesListener;
private QBSystemMessagesManager systemMessagesManager;
private QBIncomingMessagesManager incomingMessagesManager;
private DialogsManager dialogsManager;
private QBUser currentUser;
public static void start(Context context) {
Intent intent = new Intent(context, DialogsActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialogs);
googlePlayServicesHelper = new GooglePlayServicesHelper();
pushBroadcastReceiver = new PushBroadcastReceiver();
allDialogsMessagesListener = new AllDialogsMessageListener();
systemMessagesListener = new SystemMessagesListener();
dialogsManager = new DialogsManager();
currentUser = ChatHelper.getCurrentUser();
initUi();
setActionBarTitle(getString(R.string.dialogs_logged_in_as, currentUser.getFullName()));
registerQbChatListeners();
if (QbDialogHolder.getInstance().getDialogs().size() > 0) {
loadDialogsFromQb(true, true);
} else {
loadDialogsFromQb(false, true);
}
}
@Override
protected void onResume() {
super.onResume();
googlePlayServicesHelper.checkPlayServicesAvailable(this);
LocalBroadcastManager.getInstance(this).registerReceiver(pushBroadcastReceiver,
new IntentFilter(GcmConsts.ACTION_NEW_GCM_EVENT));
}
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(pushBroadcastReceiver);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterQbChatListeners();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_dialogs, menu);
this.menu = menu;
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (isProcessingResultInProgress) {
return super.onOptionsItemSelected(item);
}
switch (item.getItemId()) {
case R.id.menu_dialogs_action_logout:
userLogout();
item.setEnabled(false);
invalidateOptionsMenu();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@SuppressWarnings("unchecked")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
isProcessingResultInProgress = true;
if (requestCode == REQUEST_SELECT_PEOPLE) {
ArrayList<QBUser> selectedUsers = (ArrayList<QBUser>) data
.getSerializableExtra(SelectUsersActivity.EXTRA_QB_USERS);
if (isPrivateDialogExist(selectedUsers)) {
selectedUsers.remove(ChatHelper.getCurrentUser());
QBChatDialog existingPrivateDialog = QbDialogHolder.getInstance().getPrivateDialogWithUser(selectedUsers.get(0));
isProcessingResultInProgress = false;
ChatActivity.startForResult(DialogsActivity.this, REQUEST_DIALOG_ID_FOR_UPDATE, existingPrivateDialog);
} else {
ProgressDialogFragment.show(getSupportFragmentManager(), R.string.create_chat);
createDialog(selectedUsers);
}
} else if (requestCode == REQUEST_DIALOG_ID_FOR_UPDATE) {
if (data != null) {
String dialogId = data.getStringExtra(ChatActivity.EXTRA_DIALOG_ID);
loadUpdatedDialog(dialogId);
} else {
isProcessingResultInProgress = false;
updateDialogsList();
}
}
} else {
updateDialogsAdapter();
}
}
private boolean isPrivateDialogExist(ArrayList<QBUser> allSelectedUsers) {
ArrayList<QBUser> selectedUsers = new ArrayList<>();
selectedUsers.addAll(allSelectedUsers);
selectedUsers.remove(ChatHelper.getCurrentUser());
return selectedUsers.size() == 1 && QbDialogHolder.getInstance().hasPrivateDialogWithUser(selectedUsers.get(0));
}
private void loadUpdatedDialog(String dialogId) {
ChatHelper.getInstance().getDialogById(dialogId, new QbEntityCallbackImpl<QBChatDialog>() {
@Override
public void onSuccess(QBChatDialog result, Bundle bundle) {
isProcessingResultInProgress = false;
QbDialogHolder.getInstance().addDialog(result);
updateDialogsAdapter();
}
@Override
public void onError(QBResponseException e) {
isProcessingResultInProgress = false;
}
});
}
@Override
protected View getSnackbarAnchorView() {
return findViewById(R.id.layout_root);
}
@Override
public ActionMode startSupportActionMode(ActionMode.Callback callback) {
currentActionMode = super.startSupportActionMode(callback);
return currentActionMode;
}
private void userLogout() {
ChatHelper.getInstance().destroy();
SubscribeService.unSubscribeFromPushes(DialogsActivity.this);
SharedPrefsHelper.getInstance().removeQbUser();
LoginActivity.start(DialogsActivity.this);
QbDialogHolder.getInstance().clear();
ProgressDialogFragment.hide(getSupportFragmentManager());
finish();
}
private void updateDialogsList() {
requestBuilder.setSkip(skipRecords = 0);
loadDialogsFromQb(true, true);
}
public void onStartNewChatClick(View view) {
SelectUsersActivity.startForResult(this, REQUEST_SELECT_PEOPLE);
}
private void initUi() {
LinearLayout emptyHintLayout = _findViewById(R.id.layout_chat_empty);
ListView dialogsListView = _findViewById(R.id.list_dialogs_chats);
progressBar = _findViewById(R.id.progress_dialogs);
fab = _findViewById(R.id.fab_dialogs_new_chat);
setOnRefreshListener = _findViewById(R.id.swipy_refresh_layout);
dialogsAdapter = new DialogsAdapter(this, new ArrayList<>(QbDialogHolder.getInstance().getDialogs().values()));
TextView listHeader = (TextView) LayoutInflater.from(this)
.inflate(R.layout.include_list_hint_header, dialogsListView, false);
listHeader.setText(R.string.dialogs_list_hint);
dialogsListView.setEmptyView(emptyHintLayout);
dialogsListView.addHeaderView(listHeader, null, false);
dialogsListView.setAdapter(dialogsAdapter);
dialogsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
QBChatDialog selectedDialog = (QBChatDialog) parent.getItemAtPosition(position);
if (currentActionMode == null) {
ChatActivity.startForResult(DialogsActivity.this, REQUEST_DIALOG_ID_FOR_UPDATE, selectedDialog);
} else {
dialogsAdapter.toggleSelection(selectedDialog);
}
}
});
dialogsListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
QBChatDialog selectedDialog = (QBChatDialog) parent.getItemAtPosition(position);
startSupportActionMode(new DeleteActionModeCallback());
dialogsAdapter.selectItem(selectedDialog);
return true;
}
});
requestBuilder = new QBRequestGetBuilder();
setOnRefreshListener.setOnRefreshListener(new SwipyRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh(SwipyRefreshLayoutDirection direction) {
requestBuilder.setSkip(skipRecords += ChatHelper.DIALOG_ITEMS_PER_PAGE);
loadDialogsFromQb(true, false);
}
});
}
private void registerQbChatListeners() {
incomingMessagesManager = QBChatService.getInstance().getIncomingMessagesManager();
systemMessagesManager = QBChatService.getInstance().getSystemMessagesManager();
if (incomingMessagesManager != null) {
incomingMessagesManager.addDialogMessageListener(allDialogsMessagesListener != null
? allDialogsMessagesListener : new AllDialogsMessageListener());
}
if (systemMessagesManager != null) {
systemMessagesManager.addSystemMessageListener(systemMessagesListener != null
? systemMessagesListener : new SystemMessagesListener());
}
dialogsManager.addManagingDialogsCallbackListener(this);
}
private void unregisterQbChatListeners() {
if (incomingMessagesManager != null) {
incomingMessagesManager.removeDialogMessageListrener(allDialogsMessagesListener);
}
if (systemMessagesManager != null) {
systemMessagesManager.removeSystemMessageListener(systemMessagesListener);
}
dialogsManager.removeManagingDialogsCallbackListener(this);
}
private void createDialog(final ArrayList<QBUser> selectedUsers) {
ChatHelper.getInstance().createDialogWithSelectedUsers(selectedUsers,
new QBEntityCallback<QBChatDialog>() {
@Override
public void onSuccess(QBChatDialog dialog, Bundle args) {
isProcessingResultInProgress = false;
dialogsManager.sendSystemMessageAboutCreatingDialog(systemMessagesManager, dialog);
ChatActivity.startForResult(DialogsActivity.this, REQUEST_DIALOG_ID_FOR_UPDATE, dialog);
ProgressDialogFragment.hide(getSupportFragmentManager());
}
@Override
public void onError(QBResponseException e) {
isProcessingResultInProgress = false;
ProgressDialogFragment.hide(getSupportFragmentManager());
showErrorSnackbar(R.string.dialogs_creation_error, null, null);
}
}
);
}
private void loadDialogsFromQb(final boolean silentUpdate, final boolean clearDialogHolder) {
isProcessingResultInProgress = true;
if (!silentUpdate) {
progressBar.setVisibility(View.VISIBLE);
}
ChatHelper.getInstance().getDialogs(requestBuilder, new QBEntityCallback<ArrayList<QBChatDialog>>() {
@Override
public void onSuccess(ArrayList<QBChatDialog> dialogs, Bundle bundle) {
isProcessingResultInProgress = false;
progressBar.setVisibility(View.GONE);
setOnRefreshListener.setRefreshing(false);
if (clearDialogHolder) {
QbDialogHolder.getInstance().clear();
}
QbDialogHolder.getInstance().addDialogs(dialogs);
updateDialogsAdapter();
}
@Override
public void onError(QBResponseException e) {
isProcessingResultInProgress = false;
progressBar.setVisibility(View.GONE);
setOnRefreshListener.setRefreshing(false);
Toast.makeText(DialogsActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void updateDialogsAdapter() {
dialogsAdapter.updateList(new ArrayList<>(QbDialogHolder.getInstance().getDialogs().values()));
}
@Override
public void onDialogCreated(QBChatDialog chatDialog) {
updateDialogsAdapter();
}
@Override
public void onDialogUpdated(String chatDialog) {
updateDialogsAdapter();
}
@Override
public void onNewDialogLoaded(QBChatDialog chatDialog) {
updateDialogsAdapter();
}
private class DeleteActionModeCallback implements ActionMode.Callback {
public DeleteActionModeCallback() {
fab.hide();
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.action_mode_dialogs, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_dialogs_action_delete:
deleteSelectedDialogs();
if (currentActionMode != null) {
currentActionMode.finish();
}
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
currentActionMode = null;
dialogsAdapter.clearSelection();
fab.show();
}
private void deleteSelectedDialogs() {
final Collection<QBChatDialog> selectedDialogs = dialogsAdapter.getSelectedItems();
ChatHelper.getInstance().deleteDialogs(selectedDialogs, new QBEntityCallback<ArrayList<String>>() {
@Override
public void onSuccess(ArrayList<String> dialogsIds, Bundle bundle) {
QbDialogHolder.getInstance().deleteDialogs(dialogsIds);
updateDialogsAdapter();
}
@Override
public void onError(QBResponseException e) {
showErrorSnackbar(R.string.dialogs_deletion_error, e,
new View.OnClickListener() {
@Override
public void onClick(View v) {
deleteSelectedDialogs();
}
});
}
});
}
}
private class PushBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra(GcmConsts.EXTRA_GCM_MESSAGE);
Log.v(TAG, "Received broadcast " + intent.getAction() + " with data: " + message);
requestBuilder.setSkip(skipRecords = 0);
loadDialogsFromQb(true, true);
}
}
private class SystemMessagesListener implements QBSystemMessageListener {
@Override
public void processMessage(final QBChatMessage qbChatMessage) {
dialogsManager.onSystemMessageReceived(qbChatMessage);
}
@Override
public void processError(QBChatException e, QBChatMessage qbChatMessage) {
}
}
private class AllDialogsMessageListener extends QbChatDialogMessageListenerImp {
@Override
public void processMessage(final String dialogId, final QBChatMessage qbChatMessage, Integer senderId) {
if (!senderId.equals(ChatHelper.getCurrentUser().getId())) {
dialogsManager.onGlobalMessageReceived(dialogId, qbChatMessage);
}
}
}
}