Added Android code
[wl-app.git] / Android / app / src / main / java / com / moiseum / wolnelektury / view / search / BookSearchFragment.java
1 package com.moiseum.wolnelektury.view.search;
2
3 import android.content.Intent;
4 import android.os.Bundle;
5 import android.support.annotation.Nullable;
6 import android.support.v7.widget.LinearLayoutManager;
7 import android.support.v7.widget.RecyclerView;
8 import android.support.v7.widget.SearchView;
9 import android.view.Menu;
10 import android.view.MenuInflater;
11 import android.view.MenuItem;
12 import android.view.View;
13 import android.widget.Button;
14 import android.widget.ProgressBar;
15 import android.widget.RelativeLayout;
16 import android.widget.Toast;
17
18 import com.moiseum.wolnelektury.R;
19 import com.moiseum.wolnelektury.base.mvp.PresenterFragment;
20 import com.moiseum.wolnelektury.components.ProgressRecyclerView;
21 import com.moiseum.wolnelektury.components.recycler.EndlessRecyclerOnScrollListener;
22 import com.moiseum.wolnelektury.components.recycler.RecyclerAdapter;
23 import com.moiseum.wolnelektury.connection.models.BookModel;
24 import com.moiseum.wolnelektury.connection.models.CategoryModel;
25 import com.moiseum.wolnelektury.view.book.BookActivity;
26 import com.moiseum.wolnelektury.view.book.BookType;
27 import com.moiseum.wolnelektury.view.book.list.BooksListAdapter;
28 import com.moiseum.wolnelektury.view.search.dto.FilterDto;
29 import com.moiseum.wolnelektury.view.search.filter.FilterActivity;
30
31 import org.parceler.Parcels;
32
33 import java.util.ArrayList;
34 import java.util.List;
35
36 import butterknife.BindView;
37 import butterknife.OnClick;
38
39 import static android.app.Activity.RESULT_OK;
40 import static com.moiseum.wolnelektury.view.search.filter.FilterActivity.FILTERS_REQUEST_CODE;
41 import static com.moiseum.wolnelektury.view.search.filter.FilterActivity.RESULT_FILTERS_KEY;
42
43 /**
44  * Created by piotrostrowski on 16.11.2017.
45  */
46
47 public class BookSearchFragment extends PresenterFragment<BookSearchPresenter> implements BookSearchView, SearchView.OnQueryTextListener {
48
49         public static BookSearchFragment newInstance() {
50                 return new BookSearchFragment();
51         }
52
53         @BindView(R.id.rlFiltersContainer)
54         RelativeLayout rlFiltersContainer;
55         @BindView(R.id.rvFilters)
56         RecyclerView rvFilters;
57         @BindView(R.id.rvBooks)
58         ProgressRecyclerView<BookModel> rvBooks;
59         @BindView(R.id.pbLoadMore)
60         ProgressBar pbLoadMore;
61         @BindView(R.id.btnReloadMore)
62         Button btnReloadMore;
63
64         private SearchView svSearch;
65
66         private BookSearchFiltersAdapter filtersAdapter;
67         private RecyclerAdapter.OnItemClickListener<CategoryModel> filtersAdapterClickListener = new RecyclerAdapter
68                         .OnItemClickListener<CategoryModel>() {
69                 @Override
70                 public void onItemClicked(CategoryModel item, View view, int position) {
71                         filtersAdapter.removeItem(position);
72                         if (filtersAdapter.getItemCount() == 0) {
73                                 rlFiltersContainer.setVisibility(View.GONE);
74                         }
75                         getPresenter().removeFilter(item);
76                 }
77         };
78
79         private BooksListAdapter searchAdapter;
80         private EndlessRecyclerOnScrollListener rvBooksScrollListener = new EndlessRecyclerOnScrollListener() {
81                 @Override
82                 public void onLoadMore() {
83                         if (searchAdapter.getItemCount() > 0) {
84                                 BookModel lastItem = searchAdapter.getItem(searchAdapter.getItemCount() - 1);
85                                 getPresenter().loadMoreBooks(lastItem.getKey());
86                         }
87                 }
88         };
89         private RecyclerAdapter.OnItemClickListener<BookModel> searchAdapterClickListener = (item, view, position) -> getPresenter().bookSelected(item, position);
90
91         @Override
92         protected BookSearchPresenter createPresenter() {
93                 return new BookSearchPresenter(this);
94         }
95
96         @Override
97         public int getLayoutResourceId() {
98                 return R.layout.fragment_search;
99         }
100
101         @Override
102         public void onCreate(@Nullable Bundle savedInstanceState) {
103                 super.onCreate(savedInstanceState);
104                 setHasOptionsMenu(true);
105         }
106
107         @Override
108         public void prepareView(View view, Bundle savedInstanceState) {
109                 // Filters
110                 rvFilters.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
111                 rvFilters.setHasFixedSize(false);
112                 filtersAdapter = new BookSearchFiltersAdapter(getContext());
113                 filtersAdapter.setOnItemClickListener(filtersAdapterClickListener);
114                 rvFilters.setAdapter(filtersAdapter);
115
116                 // Search list
117                 LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
118                 searchAdapter = new BooksListAdapter(getContext());
119                 searchAdapter.setOnItemClickListener(searchAdapterClickListener);
120                 rvBooks.setLayoutManager(layoutManager);
121                 rvBooks.addOnScrollListener(rvBooksScrollListener);
122                 rvBooks.setHasFixedSize(true);
123                 rvBooks.setAdapter(searchAdapter);
124         }
125
126         @Override
127         public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
128                 super.onCreateOptionsMenu(menu, inflater);
129                 inflater.inflate(R.menu.menu_search, menu);
130         }
131
132         @Override
133         public void onPrepareOptionsMenu(Menu menu) {
134                 super.onPrepareOptionsMenu(menu);
135                 MenuItem item = menu.findItem(R.id.action_search);
136                 svSearch = (SearchView) item.getActionView();
137                 svSearch.setIconifiedByDefault(false);
138                 svSearch.setIconified(false);
139                 svSearch.setQueryRefinementEnabled(true);
140                 svSearch.setOnQueryTextListener(this);
141                 item.expandActionView();
142         }
143
144         @Override
145         public boolean onOptionsItemSelected(MenuItem item) {
146                 if (item.getItemId() == R.id.action_filter) {
147                         getPresenter().onFiltersClicked();
148                         return true;
149                 }
150                 return super.onOptionsItemSelected(item);
151         }
152
153         @Override
154         public boolean onQueryTextSubmit(String query) {
155                 getPresenter().onSearchChosen(query);
156                 svSearch.clearFocus();
157                 return true;
158         }
159
160         @Override
161         public boolean onQueryTextChange(String newText) {
162                 getPresenter().onSearchChanged(newText);
163                 return true;
164         }
165
166         @Override
167         public void onActivityResult(int requestCode, int resultCode, Intent data) {
168                 if (requestCode == FILTERS_REQUEST_CODE && resultCode == RESULT_OK && data != null && data.hasExtra(RESULT_FILTERS_KEY)) {
169                         FilterDto dto = Parcels.unwrap(data.getParcelableExtra(RESULT_FILTERS_KEY));
170                         getPresenter().updateFilters(dto);
171                 }
172                 super.onActivityResult(requestCode, resultCode, data);
173
174         }
175
176         @Override
177         public void onDestroyView() {
178                 rvBooks.removeOnScrollListener(rvBooksScrollListener);
179                 super.onDestroyView();
180         }
181
182         @OnClick(R.id.ibClearFilters)
183         public void onClearFiltersClick() {
184                 filtersAdapter.setItems(new ArrayList<>());
185                 rlFiltersContainer.setVisibility(View.GONE);
186                 getPresenter().clearFilters();
187         }
188
189         @OnClick(R.id.btnReloadMore)
190         public void onReloadMoreClicked() {
191                 btnReloadMore.setVisibility(View.GONE);
192                 pbLoadMore.setVisibility(View.VISIBLE);
193
194                 BookModel lastItem = searchAdapter.getItem(searchAdapter.getItemCount() - 1);
195                 getPresenter().loadMoreBooks(lastItem.getKey());
196         }
197
198         @Override
199         public void setData(List<BookModel> books, boolean reload) {
200                 if (reload) {
201                         rvBooks.setItems(books);
202                 } else {
203                         rvBooks.addItems(books);
204                 }
205         }
206
207         @Override
208         public void setInitialProgressVisible(boolean visible) {
209                 rvBooksScrollListener.reset();
210                 searchAdapter.clear();
211                 rvBooks.setProgressVisible(visible);
212         }
213
214         @Override
215         public void setLoadMoreProgressVisible(boolean visible) {
216                 pbLoadMore.setVisibility(visible ? View.VISIBLE : View.GONE);
217         }
218
219         @Override
220         public void showError(Exception e, boolean loadMore) {
221                 Toast.makeText(getContext(), R.string.loading_results_failed, Toast.LENGTH_SHORT).show();
222                 if (loadMore) {
223                         btnReloadMore.setVisibility(View.VISIBLE);
224                 } else {
225                         searchAdapter.clear();
226                         rvBooks.showRetryButton(() -> getPresenter().retryInitialLoad());
227                 }
228         }
229
230         @Override
231         public void presentBookDetails(String bookSlug) {
232                 startActivity(new BookActivity.BookIntent(bookSlug, BookType.TYPE_DEFAULT, getContext()));
233         }
234
235         @Override
236         public void applyFilters(List<CategoryModel> filters) {
237                 filtersAdapter.setItems(filters);
238                 rlFiltersContainer.setVisibility((filters.size() > 0) ? View.VISIBLE : View.GONE);
239         }
240
241         @Override
242         public void displayFiltersView(FilterDto filters) {
243                 FilterActivity.FilterIntent filterIntent = new FilterActivity.FilterIntent(getContext(), filters);
244                 startActivityForResult(filterIntent, FILTERS_REQUEST_CODE);
245         }
246
247         @Override
248         public void updateFavouriteState(boolean state, Integer clickedPosition) {
249                 if (clickedPosition != null) {
250                         searchAdapter.getItem(clickedPosition).setLiked(state);
251                         searchAdapter.notifyDataSetChanged();
252                 }
253         }
254 }