make search fagment handle video items

This commit is contained in:
Christian Schabesberger 2016-08-02 18:38:05 +02:00
parent 3a5b9203d8
commit 2f2334eac4
4 changed files with 236 additions and 18 deletions

View File

@ -40,7 +40,7 @@ public class ServiceList {
public static StreamingService[] getServices() { public static StreamingService[] getServices() {
return services; return services;
} }
public static StreamingService getService(int serviceId) throws ExtractionException { public static StreamingService getService(int serviceId)throws ExtractionException {
for(StreamingService s : services) { for(StreamingService s : services) {
if(s.getServiceId() == serviceId) { if(s.getServiceId() == serviceId) {
return s; return s;

View File

@ -2,14 +2,9 @@ package org.schabi.newpipe.search_fragment;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.widget.CursorAdapter;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
@ -21,19 +16,13 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.ErrorActivity; import org.schabi.newpipe.ErrorActivity;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ExtractionException; import org.schabi.newpipe.extractor.SearchResult;
import org.schabi.newpipe.extractor.SearchEngine;
import org.schabi.newpipe.extractor.ServiceList; import org.schabi.newpipe.extractor.ServiceList;
import java.io.IOException;
import java.util.List;
/** /**
* Created by Christian Schabesberger on 02.08.16. * Created by Christian Schabesberger on 02.08.16.
*/ */
@ -99,6 +88,7 @@ public class SearchInfoItemFragment extends Fragment {
private SearchView searchView = null; private SearchView searchView = null;
private SuggestionListAdapter suggestionListAdapter = null; private SuggestionListAdapter suggestionListAdapter = null;
private StreamInfoListAdapter streamInfoListAdapter = null;
// savedInstanceBundle arguments // savedInstanceBundle arguments
private static final String QUERY = "query"; private static final String QUERY = "query";
@ -144,6 +134,28 @@ public class SearchInfoItemFragment extends Fragment {
"", R.string.general_error)); "", R.string.general_error));
} }
} }
SearchWorker sw = SearchWorker.getInstance();
sw.setSearchWorkerResultListner(new SearchWorker.SearchWorkerResultListner() {
@Override
public void onResult(SearchResult result) {
streamInfoListAdapter.addVideoList(result.resultList);
}
@Override
public void onNothingFound(int stringResource) {
//setListShown(true);
Toast.makeText(getActivity(), getString(stringResource),
Toast.LENGTH_SHORT).show();
}
@Override
public void onError(String message) {
//setListShown(true);
Toast.makeText(getActivity(), message,
Toast.LENGTH_LONG).show();
}
});
} }
@Override @Override
@ -160,8 +172,12 @@ public class SearchInfoItemFragment extends Fragment {
} else { } else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount)); recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
} }
recyclerView.setAdapter(null);
streamInfoListAdapter = new StreamInfoListAdapter(getActivity(),
getActivity().findViewById(android.R.id.content));
recyclerView.setAdapter(streamInfoListAdapter);
} }
return view; return view;
} }
@ -202,7 +218,13 @@ public class SearchInfoItemFragment extends Fragment {
} }
private void search(String query) { private void search(String query) {
streamInfoListAdapter.clearVideoList();
search(query, 0);
}
private void search(String query, int page) {
SearchWorker sw = SearchWorker.getInstance();
sw.search(streamingServiceId, query, page, getActivity());
} }
private void searchSuggestions(String query) { private void searchSuggestions(String query) {
@ -216,8 +238,16 @@ public class SearchInfoItemFragment extends Fragment {
h.post(new Runnable() { h.post(new Runnable() {
@Override @Override
public void run() { public void run() {
Toast.makeText(getActivity(), getString(stringResource),
Toast.LENGTH_SHORT).show(); }
});
}
private void postNewNothingFoundToast(Handler h, final int stringResource) {
h.post(new Runnable() {
@Override
public void run() {
} }
}); });
} }

View File

@ -0,0 +1,175 @@
package org.schabi.newpipe.search_fragment;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.ErrorActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ExtractionException;
import org.schabi.newpipe.extractor.SearchEngine;
import org.schabi.newpipe.extractor.SearchResult;
import org.schabi.newpipe.extractor.ServiceList;
import java.io.IOException;
/**
* Created by the-scrabi on 02.08.16.
*/
public class SearchWorker {
private static final String TAG = SearchWorker.class.toString();
public interface SearchWorkerResultListner {
void onResult(SearchResult result);
void onNothingFound(final int stringResource);
void onError(String message);
}
private class ResultRunnable implements Runnable {
private final SearchResult result;
private int requestId = 0;
public ResultRunnable(SearchResult result, int requestId) {
this.result = result;
this.requestId = requestId;
}
@Override
public void run() {
if(this.requestId == SearchWorker.this.requestId) {
searchWorkerResultListner.onResult(result);
}
}
}
private class SearchRunnable implements Runnable {
public static final String YOUTUBE = "Youtube";
private final String query;
private final int page;
final Handler h = new Handler();
private volatile boolean runs = true;
private Activity a = null;
private int serviceId = -1;
public SearchRunnable(int serviceId, String query, int page, Activity activity, int requestId) {
this.serviceId = serviceId;
this.query = query;
this.page = page;
this.a = activity;
}
void terminate() {
runs = false;
}
@Override
public void run() {
SearchResult result = null;
SearchEngine engine = null;
try {
engine = ServiceList.getService(serviceId)
.getSearchEngineInstance(new Downloader());
} catch(ExtractionException e) {
ErrorActivity.reportError(h, a, e, null, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
Integer.toString(serviceId), query, R.string.general_error));
return;
}
try {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(a);
String searchLanguageKey = a.getString(R.string.search_language_key);
String searchLanguage = sp.getString(searchLanguageKey,
a.getString(R.string.default_language_value));
result = SearchResult
.getSearchResult(engine, query, page, searchLanguage, new Downloader());
if(runs) {
h.post(new ResultRunnable(result, requestId));
}
// look for errors during extraction
// soft errors:
if(result != null &&
!result.errors.isEmpty()) {
Log.e(TAG, "OCCURRED ERRORS DURING SEARCH EXTRACTION:");
for(Throwable e : result.errors) {
e.printStackTrace();
Log.e(TAG, "------");
}
View rootView = a.findViewById(R.id.videoitem_list);
ErrorActivity.reportError(h, a, result.errors, null, rootView,
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
/* todo: this shoudl not be assigned static */ YOUTUBE, query, R.string.light_parsing_error));
}
// hard errors:
} catch(IOException e) {
h.post(new Runnable() {
@Override
public void run() {
searchWorkerResultListner.onNothingFound(R.string.network_error);
}
});
e.printStackTrace();
} catch(final SearchEngine.NothingFoundException e) {
h.post(new Runnable() {
@Override
public void run() {
searchWorkerResultListner.onError(e.getMessage());
}
});
} catch(ExtractionException e) {
ErrorActivity.reportError(h, a, e, null, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
/* todo: this shoudl not be assigned static */
YOUTUBE, query, R.string.parsing_error));
//postNewErrorToast(h, R.string.parsing_error);
e.printStackTrace();
} catch(Exception e) {
ErrorActivity.reportError(h, a, e, null, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
/* todo: this shoudl not be assigned static */ YOUTUBE, query, R.string.general_error));
e.printStackTrace();
}
}
}
private static SearchWorker searchWorker = null;
private SearchWorkerResultListner searchWorkerResultListner = null;
private SearchRunnable runnable = null;
private int requestId = 0; //prevents running requests that have already ben expired
public static SearchWorker getInstance() {
return searchWorker == null ? (searchWorker = new SearchWorker()) : searchWorker;
}
public void setSearchWorkerResultListner(SearchWorkerResultListner listener) {
searchWorkerResultListner = listener;
}
private SearchWorker() {
}
public void search(int serviceId, String query, int page, Activity a) {
if(runnable != null) {
terminate();
} else {
runnable = new SearchRunnable(serviceId, query, page, a, requestId);
}
Thread thread = new Thread(runnable);
thread.start();
}
public void terminate() {
requestId++;
runnable.terminate();
}
}

View File

@ -1,4 +1,4 @@
package org.schabi.newpipe; package org.schabi.newpipe.search_fragment;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
@ -10,6 +10,10 @@ import android.view.ViewGroup;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import org.schabi.newpipe.ImageErrorLoadingListener;
import org.schabi.newpipe.R;
import org.schabi.newpipe.StreamInfoItemHolder;
import org.schabi.newpipe.StreamInfoItemViewCreator;
import org.schabi.newpipe.extractor.AbstractVideoInfo; import org.schabi.newpipe.extractor.AbstractVideoInfo;
import org.schabi.newpipe.extractor.StreamPreviewInfo; import org.schabi.newpipe.extractor.StreamPreviewInfo;
@ -28,12 +32,21 @@ public class StreamInfoListAdapter extends RecyclerView.Adapter<StreamInfoItemHo
private DisplayImageOptions displayImageOptions = private DisplayImageOptions displayImageOptions =
new DisplayImageOptions.Builder().cacheInMemory(true).build(); new DisplayImageOptions.Builder().cacheInMemory(true).build();
StreamInfoListAdapter(Activity a, View rootView) { StreamInfoListAdapter(Activity a, View rootView) {
activity = a; activity = a;
this.rootView = rootView; this.rootView = rootView;
} }
public void addVideoList(List<StreamPreviewInfo> videos) {
streamList.addAll(videos);
notifyDataSetChanged();
}
public void clearVideoList() {
streamList = new Vector<>();
notifyDataSetChanged();
}
@Override @Override
public int getItemCount() { public int getItemCount() {
return streamList.size(); return streamList.size();