mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 06:17:57 +01:00 
			
		
		
		
	Add library search. Closes #64
This commit is contained in:
		| @@ -3,8 +3,6 @@ package eu.kanade.tachiyomi.ui.library; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Filter; | ||||
| import android.widget.Filterable; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| @@ -12,28 +10,24 @@ import java.util.List; | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter; | ||||
| import eu.kanade.tachiyomi.R; | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga; | ||||
| import rx.Observable; | ||||
|  | ||||
| public class LibraryCategoryAdapter extends FlexibleAdapter<LibraryHolder, Manga> | ||||
|         implements Filterable { | ||||
| public class LibraryCategoryAdapter extends FlexibleAdapter<LibraryHolder, Manga> { | ||||
|  | ||||
|     List<Manga> mangas; | ||||
|     Filter filter; | ||||
|     private List<Manga> mangas; | ||||
|     private LibraryCategoryFragment fragment; | ||||
|  | ||||
|     public LibraryCategoryAdapter(LibraryCategoryFragment fragment) { | ||||
|         this.fragment = fragment; | ||||
|         mItems = new ArrayList<>(); | ||||
|         filter = new LibraryFilter(); | ||||
|         setHasStableIds(true); | ||||
|     } | ||||
|  | ||||
|     public void setItems(List<Manga> list) { | ||||
|         mItems = list; | ||||
|         notifyDataSetChanged(); | ||||
|  | ||||
|         // TODO needed for filtering? | ||||
|         mangas = list; | ||||
|         // A copy of manga that it's always unfiltered | ||||
|         mangas = new ArrayList<>(list); | ||||
|         updateDataSet(null); | ||||
|     } | ||||
|  | ||||
|     public void clear() { | ||||
| @@ -47,7 +41,16 @@ public class LibraryCategoryAdapter extends FlexibleAdapter<LibraryHolder, Manga | ||||
|  | ||||
|     @Override | ||||
|     public void updateDataSet(String param) { | ||||
|         if (mangas != null) { | ||||
|             filterItems(mangas); | ||||
|             notifyDataSetChanged(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected boolean filterObject(Manga manga, String query) { | ||||
|         return (manga.title != null && manga.title.toLowerCase().contains(query)) || | ||||
|                 (manga.author != null && manga.author.toLowerCase().contains(query)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -70,40 +73,4 @@ public class LibraryCategoryAdapter extends FlexibleAdapter<LibraryHolder, Manga | ||||
|         return fragment.recycler.getItemWidth() / 3 * 4; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Filter getFilter() { | ||||
|         return filter; | ||||
|     } | ||||
|  | ||||
|     private class LibraryFilter extends Filter { | ||||
|         @Override | ||||
|         protected FilterResults performFiltering(CharSequence charSequence) { | ||||
|             FilterResults results = new FilterResults(); | ||||
|             String query = charSequence.toString().toLowerCase(); | ||||
|  | ||||
|             if (query.length() == 0) { | ||||
|                 results.values = mangas; | ||||
|                 results.count = mangas.size(); | ||||
|             } else { | ||||
|                 List<Manga> filteredMangas = Observable.from(mangas) | ||||
|                         .filter(x -> | ||||
|                                 (x.title != null && x.title.toLowerCase().contains(query)) || | ||||
|                                 (x.author != null && x.author.toLowerCase().contains(query)) || | ||||
|                                 (x.artist != null && x.artist.toLowerCase().contains(query))) | ||||
|                         .toList() | ||||
|                         .toBlocking() | ||||
|                         .single(); | ||||
|                 results.values = filteredMangas; | ||||
|                 results.count = filteredMangas.size(); | ||||
|             } | ||||
|  | ||||
|             return results; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public void publishResults(CharSequence constraint, FilterResults results) { | ||||
|             setItems((List<Manga>) results.values); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -37,6 +37,7 @@ public class LibraryCategoryFragment extends BaseFragment | ||||
|     private List<Manga> mangas; | ||||
|  | ||||
|     private Subscription numColumnsSubscription; | ||||
|     private Subscription searchSubscription; | ||||
|  | ||||
|     public static LibraryCategoryFragment newInstance(int position) { | ||||
|         LibraryCategoryFragment fragment = new LibraryCategoryFragment(); | ||||
| @@ -77,12 +78,19 @@ public class LibraryCategoryFragment extends BaseFragment | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         searchSubscription = getLibraryPresenter().searchSubject | ||||
|                 .subscribe(text -> { | ||||
|                     adapter.setSearchText(text); | ||||
|                     adapter.updateDataSet(); | ||||
|                 }); | ||||
|  | ||||
|         return view; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onDestroyView() { | ||||
|         numColumnsSubscription.unsubscribe(); | ||||
|         searchSubscription.unsubscribe(); | ||||
|         super.onDestroyView(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,8 @@ import android.support.design.widget.AppBarLayout; | ||||
| import android.support.design.widget.TabLayout; | ||||
| import android.support.v4.view.ViewPager; | ||||
| import android.support.v7.view.ActionMode; | ||||
| import android.support.v7.widget.SearchView; | ||||
| import android.text.TextUtils; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuInflater; | ||||
| @@ -48,6 +50,7 @@ public class LibraryFragment extends BaseRxFragment<LibraryPresenter> | ||||
|     private ActionMode actionMode; | ||||
|  | ||||
|     @State int activeCategory; | ||||
|     @State String query = ""; | ||||
|  | ||||
|     public static LibraryFragment newInstance() { | ||||
|         return new LibraryFragment(); | ||||
| @@ -60,8 +63,7 @@ public class LibraryFragment extends BaseRxFragment<LibraryPresenter> | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||||
|                              Bundle savedInstanceState) { | ||||
|     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { | ||||
|         // Inflate the layout for this fragment | ||||
|         View view = inflater.inflate(R.layout.fragment_library, container, false); | ||||
|         setToolbarTitle(getString(R.string.label_library)); | ||||
| @@ -75,6 +77,10 @@ public class LibraryFragment extends BaseRxFragment<LibraryPresenter> | ||||
|         viewPager.setAdapter(adapter); | ||||
|         tabs.setupWithViewPager(viewPager); | ||||
|  | ||||
|         if (savedState != null) { | ||||
|             getPresenter().searchSubject.onNext(query); | ||||
|         } | ||||
|  | ||||
|         return view; | ||||
|     } | ||||
|  | ||||
| @@ -99,6 +105,29 @@ public class LibraryFragment extends BaseRxFragment<LibraryPresenter> | ||||
|     @Override | ||||
|     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { | ||||
|         inflater.inflate(R.menu.library, menu); | ||||
|  | ||||
|         // Initialize search menu | ||||
|         MenuItem searchItem = menu.findItem(R.id.action_search); | ||||
|         final SearchView searchView = (SearchView) searchItem.getActionView(); | ||||
|  | ||||
|         if (!TextUtils.isEmpty(query)) { | ||||
|             searchItem.expandActionView(); | ||||
|             searchView.setQuery(query, true); | ||||
|             searchView.clearFocus(); | ||||
|         } | ||||
|         searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { | ||||
|             @Override | ||||
|             public boolean onQueryTextSubmit(String query) { | ||||
|                 onSearchTextChange(query); | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean onQueryTextChange(String newText) { | ||||
|                 onSearchTextChange(newText); | ||||
|                 return true; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -115,6 +144,11 @@ public class LibraryFragment extends BaseRxFragment<LibraryPresenter> | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
|  | ||||
|     private void onSearchTextChange(String query) { | ||||
|         this.query = query; | ||||
|         getPresenter().searchSubject.onNext(query); | ||||
|     } | ||||
|  | ||||
|     private void onEditCategories() { | ||||
|         Intent intent = CategoryActivity.newIntent(getActivity()); | ||||
|         startActivity(intent); | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.event.LibraryMangasEvent; | ||||
| import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter; | ||||
| import rx.Observable; | ||||
| import rx.android.schedulers.AndroidSchedulers; | ||||
| import rx.subjects.BehaviorSubject; | ||||
|  | ||||
| public class LibraryPresenter extends BasePresenter<LibraryFragment> { | ||||
|  | ||||
| @@ -32,6 +33,8 @@ public class LibraryPresenter extends BasePresenter<LibraryFragment> { | ||||
|     protected List<Category> categories; | ||||
|     protected List<Manga> selectedMangas; | ||||
|  | ||||
|     protected BehaviorSubject<String> searchSubject; | ||||
|  | ||||
|     private static final int GET_LIBRARY = 1; | ||||
|  | ||||
|     @Override | ||||
| @@ -40,6 +43,8 @@ public class LibraryPresenter extends BasePresenter<LibraryFragment> { | ||||
|  | ||||
|         selectedMangas = new ArrayList<>(); | ||||
|  | ||||
|         searchSubject = BehaviorSubject.create(); | ||||
|  | ||||
|         restartableLatestCache(GET_LIBRARY, | ||||
|                 this::getLibraryObservable, | ||||
|                 (view, pair) -> view.onNextLibraryUpdate(pair.first, pair.second)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user