package com.hannesdorfmann.mosby3.sample.mail.search;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.hannesdorfmann.mosby3.sample.mail.MailApplication;
import com.hannesdorfmann.mosby3.sample.mail.R;
import com.hannesdorfmann.mosby3.sample.mail.base.view.BaseMailsFragment;
import com.hannesdorfmann.mosby3.sample.mail.base.view.ListAdapter;
import com.hannesdorfmann.mosby3.sample.mail.base.view.viewstate.AuthViewState;
import com.hannesdorfmann.mosby3.sample.mail.dagger.NavigationModule;
import com.hannesdorfmann.mosby3.sample.mail.model.mail.Mail;
import com.hannesdorfmann.mosby3.sample.mail.utils.BuildUtils;
import com.rengwuxian.materialedittext.MaterialEditText;
import java.util.List;
import butterknife.BindView;
/**
* @author Hannes Dorfmann
*/
public class SearchFragment extends BaseMailsFragment<SearchView, SearchPresenter>
implements SearchView {
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.searchEditView) MaterialEditText searchEditView;
private SearchComponent searchComponent;
LinearLayoutManager layoutManager;
boolean canLoadMore = true;
boolean isLoadingMore = false;
String lastQuery = "";
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override protected int getLayoutRes() {
return R.layout.fragment_search;
}
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Init toolbar
toolbar.setNavigationIcon(BuildUtils.getBackArrowDrawable(getActivity()));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
getActivity().finish();
}
});
toolbar.inflateMenu(R.menu.search_menu);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override public boolean onMenuItemClick(MenuItem menuItem) {
if (menuItem.getItemId() == R.id.search) {
loadData(false);
return true;
}
return false;
}
});
// search
searchEditView.addTextChangedListener(new TextWatcher() {
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
loadData(false);
}
@Override public void afterTextChanged(Editable s) {
}
});
// load more
layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
if (canLoadMore && !isLoadingMore && lastVisibleItemPosition == totalItemCount - 1) {
loadOlderMails();
}
}
});
}
@Override public void addOlderMails(List<Mail> older) {
SearchResultAdapter searchAdapter = getAdapter();
searchAdapter.addOlderMails(older);
if (older.isEmpty()) {
canLoadMore = false;
Toast.makeText(getActivity(), R.string.search_no_more_mails_to_load, Toast.LENGTH_SHORT)
.show();
}
}
@Override public AuthViewState<List<Mail>, SearchView> createViewState() {
return new SearchViewState();
}
@Override public SearchPresenter createPresenter() {
return searchComponent.presenter();
}
private SearchResultAdapter getAdapter() {
return (SearchResultAdapter) adapter;
}
@Override protected ListAdapter<List<Mail>> createAdapter() {
return new SearchResultAdapter(getActivity(), this, this, this);
}
@Override public void showLoadMore(boolean showLoadMore) {
getAdapter().setLoadMore(showLoadMore);
SearchViewState searchViewState = (SearchViewState) getViewState();
searchViewState.setLoadingMore(showLoadMore);
isLoadingMore = showLoadMore;
}
@Override public void loadData(boolean pullToRefresh) {
String query = getQueryString();
// Workaround to solve textwatcher problem that forces reload on screen orientation change, since
// textwatcher triggers onTextChanged() after restoring edittext after screen orientation changes
if (pullToRefresh || !query.equals(lastQuery)) {
presenter.searchFor(query, pullToRefresh);
canLoadMore = true;
lastQuery = query;
}
}
private String getQueryString() {
return searchEditView.getText().toString();
}
private void loadOlderMails() {
Mail lastMail = getAdapter().getLastMailInList();
if (lastMail != null) {
presenter.loadOlderMails(getQueryString(), lastMail);
}
}
@Override public void showSearchNotStartedYet() {
loadingView.setVisibility(View.GONE);
contentView.setVisibility(View.GONE);
errorView.setVisibility(View.GONE);
authView.setVisibility(View.GONE);
emptyView.setVisibility(View.GONE);
lastQuery = "";
SearchViewState vs = (SearchViewState) getViewState();
vs.setShowSearchNotStarted();
}
@Override protected void onErrorViewClicked() {
lastQuery = "";
super.onErrorViewClicked();
}
@Override public void onNewViewStateInstance() {
showSearchNotStartedYet();
}
@Override public void showLoadMoreError(Throwable e) {
Toast.makeText(getActivity(), R.string.error_search_load_older, Toast.LENGTH_SHORT).show();
lastQuery = "";
}
@Override protected void injectDependencies() {
searchComponent = DaggerSearchComponent.builder()
.mailAppComponent(MailApplication.getMailComponents())
.navigationModule(new NavigationModule())
.build();
searchComponent.inject(this);
}
}