package com.xabber.android.ui.fragment; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.Button; import android.widget.Filterable; import android.widget.LinearLayout; import android.widget.PopupMenu; import android.widget.TextView; import com.melnykov.fab.FloatingActionButton; import com.xabber.android.R; import com.xabber.android.data.Application; import com.xabber.android.data.SettingsManager; import com.xabber.android.data.account.AccountManager; import com.xabber.android.data.account.CommonState; import com.xabber.android.data.account.StatusMode; import com.xabber.android.data.account.listeners.OnAccountChangedListener; import com.xabber.android.data.connection.ConnectionManager; import com.xabber.android.data.entity.AccountJid; import com.xabber.android.data.message.NewMessageEvent; import com.xabber.android.data.roster.AbstractContact; import com.xabber.android.data.roster.OnContactChangedListener; import com.xabber.android.data.roster.RosterContact; import com.xabber.android.ui.activity.AccountAddActivity; import com.xabber.android.ui.activity.AccountListActivity; import com.xabber.android.ui.activity.ContactAddActivity; import com.xabber.android.ui.activity.ManagedActivity; import com.xabber.android.ui.adapter.AccountActionButtonsAdapter; import com.xabber.android.ui.adapter.UpdatableAdapter; import com.xabber.android.ui.adapter.contactlist.AccountConfiguration; import com.xabber.android.ui.adapter.contactlist.ContactListAdapter; import com.xabber.android.ui.adapter.contactlist.ContactListAdapter.ContactListAdapterListener; import com.xabber.android.ui.adapter.contactlist.ContactListState; import com.xabber.android.ui.color.AccountPainter; import com.xabber.android.ui.color.ColorManager; import com.xabber.android.ui.helper.ContextMenuHelper; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.Collection; public class ContactListFragment extends Fragment implements OnAccountChangedListener, OnContactChangedListener, ContactListAdapterListener, View.OnClickListener { private ContactListAdapter adapter; private RecyclerView recyclerView; /** * View with information shown on empty contact list. */ private View infoView; /** * Image view with connected icon. */ private View connectedView; /** * Image view with disconnected icon. */ private View disconnectedView; /** * View with help text. */ private TextView textView; /** * Button to apply help text. */ private Button buttonView; /** * Animation for disconnected view. */ private Animation animation; private AccountActionButtonsAdapter accountActionButtonsAdapter; private View scrollToChatsActionButtonContainer; private View actionButtonsContainer; private FloatingActionButton scrollToChatsActionButton; private AccountPainter accountPainter; private ContactListFragmentListener contactListFragmentListener; private LinearLayoutManager linearLayoutManager; @Override public void onAttach(Activity activity) { super.onAttach(activity); contactListFragmentListener = (ContactListFragmentListener) activity; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_contact_list, container, false); // to avoid strange bug on some 4.x androids view.setBackgroundColor(ColorManager.getInstance().getContactListBackgroundColor()); recyclerView = (RecyclerView) view.findViewById(R.id.contact_list_recycler_view); registerForContextMenu(recyclerView); adapter = new ContactListAdapter((ManagedActivity) getActivity(), this); linearLayoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(linearLayoutManager); recyclerView.setAdapter(adapter); infoView = view.findViewById(R.id.info); connectedView = infoView.findViewById(R.id.connected); disconnectedView = infoView.findViewById(R.id.disconnected); textView = (TextView) infoView.findViewById(R.id.text); buttonView = (Button) infoView.findViewById(R.id.button); animation = AnimationUtils.loadAnimation(getActivity(), R.anim.connection); accountActionButtonsAdapter = new AccountActionButtonsAdapter(getActivity(), this, (LinearLayout) view.findViewById(R.id.account_action_buttons)); accountActionButtonsAdapter.onChange(); actionButtonsContainer = view.findViewById(R.id.account_action_buttons_container); scrollToChatsActionButtonContainer = view.findViewById(R.id.fab_up_container); scrollToChatsActionButtonContainer.setOnClickListener(this); scrollToChatsActionButtonContainer.setVisibility(View.GONE); scrollToChatsActionButton = (FloatingActionButton) view.findViewById(R.id.fab_up); accountPainter = ColorManager.getInstance().getAccountPainter(); scrollToChatsActionButton.setColorNormal(accountPainter.getDefaultMainColor()); scrollToChatsActionButton.setColorPressed(accountPainter.getDefaultDarkColor()); return view; } @Override public void onResume() { super.onResume(); EventBus.getDefault().register(this); Application.getInstance().addUIListener(OnAccountChangedListener.class, this); Application.getInstance().addUIListener(OnContactChangedListener.class, this); adapter.onChange(); scrollToChatsActionButton.setColorNormal(accountPainter.getDefaultMainColor()); scrollToChatsActionButton.setColorPressed(accountPainter.getDefaultDarkColor()); if (SettingsManager.contactsShowPanel()) { actionButtonsContainer.setVisibility(View.VISIBLE); } else { actionButtonsContainer.setVisibility(View.GONE); } } @Override public void onPause() { super.onPause(); unregisterListeners(); } @Override public void onDetach() { super.onDetach(); contactListFragmentListener = null; } @Override public void onAccountsChanged(Collection<AccountJid> accounts) { adapter.refreshRequest(); scrollToChatsActionButton.setColorNormal(accountPainter.getDefaultMainColor()); scrollToChatsActionButton.setColorPressed(accountPainter.getDefaultDarkColor()); } @Subscribe(threadMode = ThreadMode.MAIN) public void onNewMessageEvent(NewMessageEvent event) { adapter.refreshRequest(); } @Override public void onContactListChanged(CommonState commonState, boolean hasContacts, boolean hasVisibleContacts, boolean isFilterEnabled) { if (adapter.isHasActiveChats()) { scrollToChatsActionButtonContainer.setVisibility(View.VISIBLE); } else { scrollToChatsActionButtonContainer.setVisibility(View.GONE); } contactListFragmentListener.onContactListChange(commonState); if (hasVisibleContacts) { infoView.setVisibility(View.GONE); disconnectedView.clearAnimation(); return; } infoView.setVisibility(View.VISIBLE); final int text; final int button; final ContactListState state; final View.OnClickListener listener; if (isFilterEnabled) { if (commonState == CommonState.online) { state = ContactListState.online; } else if (commonState == CommonState.roster || commonState == CommonState.connecting) { state = ContactListState.connecting; } else { state = ContactListState.offline; } text = R.string.application_state_no_online; button = 0; listener = null; } else if (hasContacts) { state = ContactListState.online; text = R.string.application_state_no_online; button = R.string.application_action_no_online; listener = new View.OnClickListener() { @Override public void onClick(View view) { SettingsManager.setContactsShowOffline(true); adapter.onChange(); } }; } else if (commonState == CommonState.online) { state = ContactListState.online; text = R.string.application_state_no_contacts; button = R.string.application_action_no_contacts; listener = new View.OnClickListener() { @Override public void onClick(View view) { startActivity(ContactAddActivity.createIntent(getActivity())); } }; } else if (commonState == CommonState.roster) { state = ContactListState.connecting; text = R.string.application_state_roster; button = 0; listener = null; } else if (commonState == CommonState.connecting) { state = ContactListState.connecting; text = R.string.application_state_connecting; button = 0; listener = null; } else if (commonState == CommonState.waiting) { state = ContactListState.offline; text = R.string.application_state_waiting; button = R.string.application_action_waiting; listener = new View.OnClickListener() { @Override public void onClick(View view) { ConnectionManager.getInstance().connectAll(); } }; } else if (commonState == CommonState.offline) { state = ContactListState.offline; text = R.string.application_state_offline; button = R.string.application_action_offline; listener = new View.OnClickListener() { @Override public void onClick(View view) { AccountManager.getInstance().setStatus( StatusMode.available, null); } }; } else if (commonState == CommonState.disabled) { state = ContactListState.offline; text = R.string.application_state_disabled; button = R.string.application_action_disabled; listener = new View.OnClickListener() { @Override public void onClick(View view) { startActivity(AccountListActivity.createIntent(getActivity())); } }; } else if (commonState == CommonState.empty) { state = ContactListState.offline; text = R.string.application_state_empty; button = R.string.application_action_empty; listener = new View.OnClickListener() { @Override public void onClick(View view) { startActivity(AccountAddActivity.createIntent(getActivity())); } }; } else { throw new IllegalStateException(); } if (state == ContactListState.offline) { connectedView.setVisibility(View.INVISIBLE); disconnectedView.setVisibility(View.VISIBLE); disconnectedView.clearAnimation(); } else if (state == ContactListState.connecting) { connectedView.setVisibility(View.VISIBLE); disconnectedView.setVisibility(View.VISIBLE); if (disconnectedView.getAnimation() == null) { disconnectedView.startAnimation(animation); } } else { connectedView.setVisibility(View.VISIBLE); disconnectedView.setVisibility(View.INVISIBLE); disconnectedView.clearAnimation(); } textView.setText(text); if (button == 0) { buttonView.setVisibility(View.GONE); } else { buttonView.setVisibility(View.VISIBLE); buttonView.setText(button); } buttonView.setOnClickListener(listener); } /** * Force stop contact list updates before pause or application close. */ public void unregisterListeners() { EventBus.getDefault().unregister(this); Application.getInstance().removeUIListener(OnAccountChangedListener.class, this); Application.getInstance().removeUIListener(OnContactChangedListener.class, this); adapter.removeRefreshRequests(); } public UpdatableAdapter getAdapter() { return adapter; } public Filterable getFilterableAdapter() { return adapter; } /** * Scroll contact list to specified account. * * @param account */ void scrollTo(AccountJid account) { long count = adapter.getItemCount(); for (int position = 0; position < (int) count; position++) { Object itemAtPosition = adapter.getItem(position); if (itemAtPosition != null && itemAtPosition instanceof AccountConfiguration && ((AccountConfiguration)itemAtPosition).getAccount().equals(account)) { linearLayoutManager.scrollToPositionWithOffset(position, 0); break; } } } /** * Filter out contact list for selected account. * * @param account */ void setSelectedAccount(AccountJid account) { if (account.equals(AccountManager.getInstance().getSelectedAccount())) { SettingsManager.setContactsSelectedAccount(null); } else { SettingsManager.setContactsSelectedAccount(account); } adapter.onChange(); } /** * Scroll to the top of contact list. */ public void scrollUp() { recyclerView.scrollToPosition(0); } @Override public void onClick(View view) { if (view.getId() == R.id.fab_up_container) { scrollUp(); return; } AccountJid account = accountActionButtonsAdapter.getItemForView(view); if (account == null) { // Check for tap on account in the title return; } if (!SettingsManager.contactsShowAccounts()) { if (AccountManager.getInstance().getEnabledAccounts().size() < 2) { scrollUp(); } else { setSelectedAccount(account); rebuild(); } } else { scrollTo(account); } } public void onAccountsChanged() { accountActionButtonsAdapter.onChange(); } public void rebuild() { accountActionButtonsAdapter.rebuild(); } public interface ContactListFragmentListener { void onContactClick(AbstractContact contact); void onContactListChange(CommonState commonState); } @Override public void onContactClick(AbstractContact contact) { contactListFragmentListener.onContactClick(contact); } @Override public void onAccountMenuClick(AccountJid accountJid, View view) { PopupMenu popup = new PopupMenu(getActivity(), view); popup.inflate(R.menu.item_account_group); ContextMenuHelper.setUpAccountMenu((ManagedActivity) getActivity(), adapter, accountJid, popup.getMenu()); popup.show(); } @Override public void onContactsChanged(Collection<RosterContact> addresses) { adapter.refreshRequest(); } }