diff --git a/app/build.gradle b/app/build.gradle index 8a0ce83..8b4c10d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "net.schueller.peertube" minSdkVersion 23 targetSdkVersion 28 - versionCode 104 - versionName "1.0.4" + versionCode 105 + versionName "1.0.5" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 80cd260..44be243 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,28 +16,18 @@ android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> - - - - - - - - - + + - + android:resource="@xml/searchable"> + (), SearchActivity.this); - recyclerView.setAdapter(videoAdapter); - - loadVideos(currentStart, count, sort, query, filter); - - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - } - - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - - if (dy > 0) { - // is at end of list? - if(!recyclerView.canScrollVertically(RecyclerView.FOCUS_DOWN)){ - if (!isLoading) { - currentStart = currentStart + count; - loadVideos(currentStart, count, sort, query, filter); - } - } - } - - } - }); - - swipeRefreshLayout.setOnRefreshListener(() -> { - // Refresh items - if (!isLoading) { - currentStart = 0; - loadVideos(currentStart, count, sort, query, filter); - } - }); - - } - - - private void loadVideos(int start, int count, String sort, String search, String filter) { - - isLoading = true; - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - String nsfw = sharedPref.getBoolean("pref_show_nsfw", false) ? "both" : "false"; - - String apiBaseURL = APIUrlHelper.getUrlWithVersion(this); - - GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); - - Call call = service.searchVideosData(start, count, sort, nsfw, search); - - /*Log the URL called*/ - Log.d("URL Called", call.request().url() + ""); -// Toast.makeText(VideoListActivity.this, "URL Called: " + call.request().url(), Toast.LENGTH_SHORT).show(); - - call.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - - if (currentStart == 0) { - videoAdapter.clearData(); - } - - if (response.body() != null) { - videoAdapter.setData(response.body().getVideoArrayList()); - } - isLoading = false; - swipeRefreshLayout.setRefreshing(false); - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.wtf("err", t.fillInStackTrace()); - Toast.makeText(SearchActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show(); - isLoading = false; - swipeRefreshLayout.setRefreshing(false); - } - }); - } - - - - @Override - protected void onNewIntent(Intent intent) { - setIntent(intent); - handleIntent(intent); - } - - private void handleIntent(Intent intent) { - if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - String query = intent.getStringExtra(SearchManager.QUERY); - Log.v("Search Activity", query); - createList(query); - } - } - - @Override - public boolean onSearchRequested() { - Bundle appData = new Bundle(); - startSearch(null, false, appData, false); - return true; - } -} diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java index 6a921bc..5ef84c4 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -1,12 +1,15 @@ package net.schueller.peertube.activity; import android.Manifest; -import android.app.Activity; +import android.app.SearchManager; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.preference.PreferenceManager; +import android.provider.SearchRecentSuggestions; import android.support.annotation.NonNull; +import android.support.design.bottomnavigation.LabelVisibilityMode; import android.support.v4.app.ActivityCompat; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; @@ -14,11 +17,14 @@ import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SearchView; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; import android.widget.Toast; //import com.google.android.gms.common.GooglePlayServicesNotAvailableException; @@ -37,6 +43,7 @@ import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.model.VideoList; import net.schueller.peertube.network.GetVideoDataService; import net.schueller.peertube.network.RetrofitInstance; +import net.schueller.peertube.provider.SearchSuggestionsProvider; import java.util.ArrayList; @@ -58,6 +65,10 @@ public class VideoListActivity extends AppCompatActivity { private int count = 12; private String sort = "-createdAt"; private String filter = ""; + private String searchQuery = ""; + + private TextView emptyView; + private RecyclerView recyclerView; private boolean isLoading = false; @@ -124,7 +135,7 @@ public class VideoListActivity extends AppCompatActivity { BottomNavigationViewEx navigation = findViewById(R.id.navigation); navigation.enableAnimation(false); - navigation.setLabelVisibilityMode(1); // enableShiftingMode + navigation.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); // enableShiftingMode navigation.setItemHorizontalTranslationEnabled(false); // enableItemShiftingMode Menu navMenu = navigation.getMenu(); @@ -151,16 +162,49 @@ public class VideoListActivity extends AppCompatActivity { inflater.inflate(R.menu.menu_main, menu); // Set an icon in the ActionBar - menu.findItem(R.id.action_search).setIcon( - new IconDrawable(this, FontAwesomeIcons.fa_search) - .colorRes(R.color.cardview_light_background) - .actionBarSize()); - menu.findItem(R.id.action_settings).setIcon( new IconDrawable(this, FontAwesomeIcons.fa_cog) .colorRes(R.color.cardview_light_background) .actionBarSize()); + + MenuItem searchMenuItem = menu.findItem(R.id.action_search); + searchMenuItem.setIcon( + new IconDrawable(this, FontAwesomeIcons.fa_search) + .colorRes(R.color.cardview_light_background) + .actionBarSize()); + + // Get the SearchView and set the searchable configuration + SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); + SearchView searchView = (SearchView) searchMenuItem.getActionView(); + + // Assumes current activity is the searchable activity + searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); + searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default + searchView.setQueryRefinementEnabled(true); + + searchMenuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem menuItem) { + return true; + } + + @Override + public boolean onMenuItemActionCollapse(MenuItem menuItem) { + searchQuery = ""; + Log.d(TAG, "onMenuItemActionCollapse: "); + loadVideos(0, count, sort, filter); + return true; + } + }); + + // TODO, this doesn't work + searchManager.setOnDismissListener(() -> { + searchQuery = ""; + Log.d(TAG, "onDismiss: "); + loadVideos(0, count, sort, filter); + }); + return true; } @@ -175,7 +219,6 @@ public class VideoListActivity extends AppCompatActivity { // action with ID action_refresh was selected case R.id.action_search: //Toast.makeText(this, "Search Selected", Toast.LENGTH_SHORT).show(); - onSearchRequested(); return false; case R.id.action_settings: @@ -192,9 +235,11 @@ public class VideoListActivity extends AppCompatActivity { } private void createList() { - RecyclerView recyclerView = findViewById(R.id.recyclerView); + recyclerView = findViewById(R.id.recyclerView); swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout); + emptyView = findViewById(R.id.empty_view); + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(VideoListActivity.this); recyclerView.setLayoutManager(layoutManager); @@ -246,7 +291,12 @@ public class VideoListActivity extends AppCompatActivity { GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); - Call call = service.getVideosData(start, count, sort, nsfw); + Call call; + if (!searchQuery.equals("")) { + call = service.searchVideosData(start, count, sort, nsfw, searchQuery); + } else { + call = service.getVideosData(start, count, sort, nsfw); + } /*Log the URL called*/ Log.d("URL Called", call.request().url() + ""); @@ -263,6 +313,17 @@ public class VideoListActivity extends AppCompatActivity { if (response.body() != null) { videoAdapter.setData(response.body().getVideoArrayList()); } + + // no results show no results message + if (currentStart == 0 && videoAdapter.getItemCount() == 0) { + emptyView.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.GONE); + + } else { + emptyView.setVisibility(View.GONE); + recyclerView.setVisibility(View.VISIBLE); + } + isLoading = false; swipeRefreshLayout.setRefreshing(false); } @@ -303,4 +364,37 @@ public class VideoListActivity extends AppCompatActivity { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); } } + + @Override + protected void onNewIntent(Intent intent) { + setIntent(intent); + handleIntent(intent); + } + + private void handleIntent(Intent intent) { + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + String query = intent.getStringExtra(SearchManager.QUERY); + + SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, + SearchSuggestionsProvider.AUTHORITY, + SearchSuggestionsProvider.MODE); + + // Save recent searches + suggestions.saveRecentQuery(query, null); + + searchQuery = query; + + loadVideos(0, count, sort, filter); + + } + } + + @Override + public boolean onSearchRequested() { + Bundle appData = new Bundle(); + startSearch(null, false, appData, false); + return true; + } + + } diff --git a/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java b/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java index 6e60f4f..cfed405 100644 --- a/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java +++ b/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java @@ -3,6 +3,7 @@ package net.schueller.peertube.helper; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import android.webkit.URLUtil; import net.schueller.peertube.R; @@ -10,7 +11,13 @@ public class APIUrlHelper{ public static String getUrl(Context context) { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - return sharedPref.getString("pref_api_base", context.getResources().getString(R.string.pref_default_api_base_url)); + + // validate URL is valid + String URL = sharedPref.getString("pref_api_base", context.getResources().getString(R.string.pref_default_api_base_url)); + if (!URLUtil.isValidUrl(URL)) { + return "http://invalid"; + } + return URL; } public static String getUrlWithVersion(Context context) { diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml deleted file mode 100644 index 66a4a72..0000000 --- a/app/src/main/res/layout/activity_search.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_video_list.xml b/app/src/main/res/layout/activity_video_list.xml index 787af75..354e31b 100644 --- a/app/src/main/res/layout/activity_video_list.xml +++ b/app/src/main/res/layout/activity_video_list.xml @@ -18,6 +18,15 @@ layout="@layout/tool_bar" /> + + + + - + app:showAsAction="always|collapseActionView" + app:actionViewClass="android.support.v7.widget.SearchView" /> Version Search PeerTube Search + No Results