Added Android code
[wl-app.git] / Android / app / src / main / java / com / moiseum / wolnelektury / view / search / BookSearchPresenter.java
diff --git a/Android/app/src/main/java/com/moiseum/wolnelektury/view/search/BookSearchPresenter.java b/Android/app/src/main/java/com/moiseum/wolnelektury/view/search/BookSearchPresenter.java
new file mode 100644 (file)
index 0000000..fef67ac
--- /dev/null
@@ -0,0 +1,223 @@
+package com.moiseum.wolnelektury.view.search;
+
+import android.os.Bundle;
+import android.os.Handler;
+
+import com.moiseum.wolnelektury.R;
+import com.moiseum.wolnelektury.base.WLApplication;
+import com.moiseum.wolnelektury.base.mvp.FragmentPresenter;
+import com.moiseum.wolnelektury.connection.RestClient;
+import com.moiseum.wolnelektury.connection.RestClientCallback;
+import com.moiseum.wolnelektury.connection.models.BookModel;
+import com.moiseum.wolnelektury.connection.models.CategoryModel;
+import com.moiseum.wolnelektury.connection.services.BooksService;
+import com.moiseum.wolnelektury.utils.StringUtils;
+import com.moiseum.wolnelektury.events.BookFavouriteEvent;
+import com.moiseum.wolnelektury.view.search.dto.FilterDto;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import retrofit2.Call;
+
+/**
+ * Created by piotrostrowski on 16.11.2017.
+ */
+
+class BookSearchPresenter extends FragmentPresenter<BookSearchView> {
+
+       private static final String ONLY_LECTURES_SLUG = "only_lectures_slug";
+       private static final String HAS_AUDIOBOOK_SLUG = "has_audiobook_slug";
+       private static final long TWO_SECONDS = 2000;
+
+       private final String lectureFilterName;
+       private final String audiobookFilterName;
+
+       private RestClient client = WLApplication.getInstance().getRestClient();
+
+       private FilterDto filters;
+       private String lastKey;
+       private String searchQuery;
+       private String temporarySearchText;
+       private Integer clickedPosition;
+
+       private Call<List<BookModel>> currentCall;
+
+       private Handler searchHandler;
+       private Runnable searchHandlerRunnable = new Runnable() {
+               @Override
+               public void run() {
+                       searchQuery = temporarySearchText;
+                       loadBooks(true);
+               }
+       };
+
+       BookSearchPresenter(BookSearchView view) {
+               super(view);
+               lectureFilterName = getView().getContext().getString(R.string.lectures);
+               audiobookFilterName = getView().getContext().getString(R.string.audiobook);
+
+               filters = new FilterDto();
+               lastKey = null;
+               searchQuery = null;
+       }
+
+       @Override
+       public void onViewCreated(Bundle savedInstanceState) {
+               super.onViewCreated(savedInstanceState);
+               loadBooks(true);
+               EventBus.getDefault().register(this);
+       }
+
+       @Override
+       public void onDestroy() {
+               super.onDestroy();
+               if (currentCall != null) {
+                       currentCall.cancel();
+               }
+               if (searchHandler != null) {
+                       searchHandler.removeCallbacks(searchHandlerRunnable);
+               }
+               EventBus.getDefault().unregister(this);
+       }
+
+       @SuppressWarnings("unused")
+       @Subscribe(threadMode = ThreadMode.MAIN)
+       public void onFavouriteStateChanged(BookFavouriteEvent event) {
+               getView().updateFavouriteState(event.getState(), clickedPosition);
+       }
+
+       void bookSelected(BookModel item, int position) {
+               clickedPosition = position;
+               getView().presentBookDetails(item.getSlug());
+       }
+
+       void updateFilters(FilterDto dto) {
+               filters = dto;
+               List<CategoryModel> flatteredFilters = new ArrayList<>();
+               if (dto.isLecture()) {
+                       CategoryModel lectureModel = new CategoryModel();
+                       lectureModel.setName(lectureFilterName);
+                       lectureModel.setSlug(ONLY_LECTURES_SLUG);
+                       flatteredFilters.add(lectureModel);
+               }
+               if (dto.isAudiobook()) {
+                       CategoryModel audiobookModel = new CategoryModel();
+                       audiobookModel.setName(audiobookFilterName);
+                       audiobookModel.setSlug(HAS_AUDIOBOOK_SLUG);
+                       flatteredFilters.add(audiobookModel);
+               }
+               flatteredFilters.addAll(dto.getFilteredEpochs());
+               flatteredFilters.addAll(dto.getFilteredGenres());
+               flatteredFilters.addAll(dto.getFilteredKinds());
+               getView().applyFilters(flatteredFilters);
+               loadBooks(true);
+       }
+
+       void removeFilter(CategoryModel item) {
+               if (ONLY_LECTURES_SLUG.equals(item.getSlug())) {
+                       filters.setLecture(false);
+               } else if (HAS_AUDIOBOOK_SLUG.equals(item.getSlug())) {
+                       filters.setAudiobook(false);
+               } else if (filters.getFilteredEpochs().contains(item)) {
+                       filters.getFilteredEpochs().remove(item);
+               } else if (filters.getFilteredGenres().contains(item)) {
+                       filters.getFilteredGenres().remove(item);
+               } else if (filters.getFilteredKinds().contains(item)) {
+                       filters.getFilteredKinds().remove(item);
+               }
+               loadBooks(true);
+       }
+
+       void onFiltersClicked() {
+               getView().displayFiltersView(filters);
+       }
+
+       void clearFilters() {
+               filters = new FilterDto();
+               lastKey = null;
+               loadBooks(true);
+       }
+
+       void loadMoreBooks(final String key) {
+               lastKey = key;
+               loadBooks(false);
+       }
+
+       void onSearchChosen(String query) {
+               if (query.length() == 0) {
+                       query = null;
+               }
+               searchQuery = query;
+               loadBooks(true);
+       }
+
+       void onSearchChanged(String newText) {
+               if (searchHandler != null) {
+                       searchHandler.removeCallbacks(searchHandlerRunnable);
+               }
+
+               if (newText.length() == 0) {
+                       onSearchChosen(newText);
+               } else {
+                       temporarySearchText = newText;
+                       searchHandler = new Handler();
+                       searchHandler.postDelayed(searchHandlerRunnable, TWO_SECONDS);
+               }
+       }
+
+       void retryInitialLoad() {
+               loadBooks(true);
+       }
+
+       private void loadBooks(final boolean reset) {
+               if (reset) {
+                       lastKey = null;
+                       getView().setInitialProgressVisible(true);
+               } else {
+                       getView().setLoadMoreProgressVisible(true);
+               }
+               currentCall = client.call(new RestClientCallback<List<BookModel>, BooksService>() {
+                       @Override
+                       public void onSuccess(List<BookModel> data) {
+                               hideProgress();
+                               getView().setData(data, reset);
+                       }
+
+                       @Override
+                       public void onFailure(Exception e) {
+                               hideProgress();
+                               getView().showError(e, false);
+                       }
+
+                       @Override
+                       public void onCancel() {
+                               //nop
+                       }
+
+                       @Override
+                       public Call<List<BookModel>> execute(BooksService service) {
+                               return service.getSearchBooks(searchQuery,
+                                               StringUtils.joinSlugs(filters.getFilteredEpochs(), ","),
+                                               StringUtils.joinSlugs(filters.getFilteredGenres(), ","),
+                                               StringUtils.joinSlugs(filters.getFilteredKinds(), ","),
+                                               filters.isAudiobook() ? true : null,
+                                               filters.isLecture() ? true : null,
+                                               lastKey,
+                                               RestClient.PAGINATION_LIMIT);
+                       }
+
+                       private void hideProgress() {
+                               if (reset) {
+                                       getView().setInitialProgressVisible(false);
+                               } else {
+                                       getView().setLoadMoreProgressVisible(false);
+                               }
+                       }
+               }, BooksService.class);
+       }
+}