implement search functionality

This commit is contained in:
dkanada 2020-05-02 17:00:27 +09:00
commit ce2f3104ab
2 changed files with 104 additions and 68 deletions

View file

@ -1,14 +1,13 @@
package com.kabouzeid.gramophone.ui.activities;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@ -18,31 +17,40 @@ import com.kabouzeid.appthemehelper.ThemeStore;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.SearchAdapter;
import com.kabouzeid.gramophone.interfaces.LoaderIds;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.interfaces.MediaCallback;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
import com.kabouzeid.gramophone.util.QueryUtil;
import com.kabouzeid.gramophone.util.Util;
import java.util.ArrayList;
import org.jellyfin.apiclient.model.querying.ItemQuery;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class SearchActivity extends AbsMusicServiceActivity implements SearchView.OnQueryTextListener, LoaderManager.LoaderCallbacks<List<Object>> {
public class SearchActivity extends AbsMusicServiceActivity implements SearchView.OnQueryTextListener {
public static final String QUERY = "query";
private static final int LOADER_ID = LoaderIds.SEARCH_ACTIVITY;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(android.R.id.empty)
TextView empty;
SearchView searchView;
private Handler handler;
private SearchAdapter adapter;
private String query;
@ -66,8 +74,8 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
empty.setVisibility(adapter.getItemCount() < 1 ? View.VISIBLE : View.GONE);
}
});
recyclerView.setAdapter(adapter);
recyclerView.setAdapter(adapter);
recyclerView.setOnTouchListener((v, event) -> {
hideSoftKeyboard();
return false;
@ -75,11 +83,11 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
setUpToolBar();
handler = new Handler();
if (savedInstanceState != null) {
query = savedInstanceState.getString(QUERY);
search(query);
}
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
}
@Override
@ -91,7 +99,7 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
private void setUpToolBar() {
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
setSupportActionBar(toolbar);
//noinspection ConstantConditions
// noinspection ConstantConditions
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@ -129,18 +137,39 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
private void search(@NonNull String query) {
this.query = query;
getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
ItemQuery itemQuery = new ItemQuery();
itemQuery.setSearchTerm(query);
QueryUtil.getItems(itemQuery, new MediaCallback() {
@Override
public void onLoadMedia(List<?> media) {
Collections.sort(media, new Comparator<Object>() {
public int compare(Object one, Object two) {
if (one.getClass() == Album.class || one.getClass() == Artist.class) {
if (two.getClass() == Song.class) return -1;
}
if (two.getClass() == Album.class || two.getClass() == Artist.class) {
if (one.getClass() == Song.class) return 1;
}
return 0;
}
});
adapter.swapDataSet((List<Object>) media);
}
});
}
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
}
@Override
@ -151,7 +180,14 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
@Override
public boolean onQueryTextChange(String newText) {
search(newText);
handler.removeCallbacksAndMessages(null);
handler.postDelayed(new Runnable() {
@Override
public void run() {
search(newText);
}
}, 1000);
return false;
}
@ -161,34 +197,4 @@ public class SearchActivity extends AbsMusicServiceActivity implements SearchVie
searchView.clearFocus();
}
}
@Override
public Loader<List<Object>> onCreateLoader(int id, Bundle args) {
return new AsyncSearchResultLoader(this, query);
}
@Override
public void onLoadFinished(Loader<List<Object>> loader, List<Object> data) {
adapter.swapDataSet(data);
}
@Override
public void onLoaderReset(Loader<List<Object>> loader) {
adapter.swapDataSet(Collections.emptyList());
}
private static class AsyncSearchResultLoader extends WrappedAsyncTaskLoader<List<Object>> {
private final String query;
public AsyncSearchResultLoader(Context context, String query) {
super(context);
this.query = query;
}
@Override
public List<Object> loadInBackground() {
List<Object> results = new ArrayList<>();
return results;
}
}
}

View file

@ -10,6 +10,7 @@ import com.kabouzeid.gramophone.model.Song;
import org.jellyfin.apiclient.interaction.Response;
import org.jellyfin.apiclient.model.dto.BaseItemDto;
import org.jellyfin.apiclient.model.dto.BaseItemType;
import org.jellyfin.apiclient.model.querying.ArtistsQuery;
import org.jellyfin.apiclient.model.querying.ItemFields;
import org.jellyfin.apiclient.model.querying.ItemQuery;
@ -92,6 +93,35 @@ public class QueryUtil {
});
}
public static void getItems(ItemQuery query, MediaCallback callback) {
query.setIncludeItemTypes(new String[]{"MusicArtist", "MusicAlbum", "Audio"});
query.setUserId(App.getApiClient().getCurrentUserId());
query.setLimit(40);
query.setRecursive(true);
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
@Override
public void onResponse(ItemsResult result) {
List<Object> items = new ArrayList<>();
for (BaseItemDto itemDto : result.getItems()) {
if (itemDto.getBaseItemType() == BaseItemType.MusicArtist) {
items.add(new Artist(itemDto));
} else if (itemDto.getBaseItemType() == BaseItemType.MusicAlbum) {
items.add(new Album(itemDto));
} else {
items.add(new Song(itemDto));
}
}
callback.onLoadMedia(items);
}
@Override
public void onError(Exception exception) {
exception.printStackTrace();
}
});
}
public static void getAlbums(ItemQuery query, MediaCallback callback) {
query.setIncludeItemTypes(new String[]{"MusicAlbum"});
query.setUserId(App.getApiClient().getCurrentUserId());
@ -132,30 +162,6 @@ public class QueryUtil {
});
}
public static void getSongs(ItemQuery query, MediaCallback callback) {
query.setIncludeItemTypes(new String[]{"Audio"});
query.setUserId(App.getApiClient().getCurrentUserId());
query.setLimit(100);
query.setRecursive(true);
if (currentLibrary != null && query.getParentId() == null) query.setParentId(currentLibrary.getId());
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
@Override
public void onResponse(ItemsResult result) {
List<Song> songs = new ArrayList<>();
for (BaseItemDto itemDto : result.getItems()) {
songs.add(new Song(itemDto));
}
callback.onLoadMedia(songs);
}
@Override
public void onError(Exception exception) {
exception.printStackTrace();
}
});
}
public static void getArtists(MediaCallback callback) {
ArtistsQuery query = new ArtistsQuery();
query.setFields(new ItemFields[]{ItemFields.Genres});
@ -196,4 +202,28 @@ public class QueryUtil {
}
});
}
public static void getSongs(ItemQuery query, MediaCallback callback) {
query.setIncludeItemTypes(new String[]{"Audio"});
query.setUserId(App.getApiClient().getCurrentUserId());
query.setLimit(100);
query.setRecursive(true);
if (currentLibrary != null && query.getParentId() == null) query.setParentId(currentLibrary.getId());
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
@Override
public void onResponse(ItemsResult result) {
List<Song> songs = new ArrayList<>();
for (BaseItemDto itemDto : result.getItems()) {
songs.add(new Song(itemDto));
}
callback.onLoadMedia(songs);
}
@Override
public void onError(Exception exception) {
exception.printStackTrace();
}
});
}
}