mirror of
https://git.mihon.tech/mihonapp/mihon
synced 2024-11-23 21:55:57 +03:00
Add library search. Closes #64
This commit is contained in:
parent
ed06469885
commit
57ba368ae0
5 changed files with 63 additions and 53 deletions
|
@ -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));
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
|
||||
|
||||
<!--
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:title="@string/action_search"
|
||||
android:icon="@drawable/ic_action_search"
|
||||
android:orderInCategory="100"
|
||||
app:showAsAction="collapseActionView|ifRoom"
|
||||
app:actionViewClass="android.support.v7.widget.SearchView" />
|
||||
-->
|
||||
|
||||
<item
|
||||
android:id="@+id/action_refresh"
|
||||
android:title="@string/action_refresh"
|
||||
android:icon="@drawable/ic_action_refresh"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
|
|
Loading…
Reference in a new issue