Merge pull request #33 from sschueller/develop

Release 1.0.5
This commit is contained in:
Stefan Schüller 2018-12-02 17:32:48 +01:00 committed by GitHub
commit 152ccbd3ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 133 additions and 245 deletions

View File

@ -6,8 +6,8 @@ android {
applicationId "net.schueller.peertube" applicationId "net.schueller.peertube"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 28 targetSdkVersion 28
versionCode 104 versionCode 105
versionName "1.0.4" versionName "1.0.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])

View File

@ -16,28 +16,18 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning">
<meta-data
android:name="android.app.default_searchable"
android:value=".activity.SearchActivity" />
<activity android:name=".activity.VideoListActivity"> <activity android:name=".activity.VideoListActivity"
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.SearchActivity"
android:label="@string/title_activity_search"
android:launchMode="singleTop"> android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SEARCH" /> <action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.app.searchable" android:name="android.app.searchable"
android:resource="@xml/searchable" /> android:resource="@xml/searchable">
</meta-data>
</activity> </activity>
<activity <activity
android:name=".activity.LoginActivity" android:name=".activity.LoginActivity"

View File

@ -1,177 +0,0 @@
package net.schueller.peertube.activity;
import android.app.SearchManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.provider.SearchRecentSuggestions;
import android.support.annotation.NonNull;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;
import net.schueller.peertube.R;
import net.schueller.peertube.adapter.VideoAdapter;
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;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
// TODO: cleanup, this code partially is duplicated from VideoList Activity and should be seperated out
public class SearchActivity extends AppCompatActivity {
private VideoAdapter videoAdapter;
private SwipeRefreshLayout swipeRefreshLayout;
private int currentStart = 0;
private int count = 12;
private String sort = "-match";
private String filter = "";
private boolean isLoading = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
Intent intent = getIntent();
// do search
handleIntent(intent);
// handle search suggestions
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);
}
}
private void createList(String query) {
RecyclerView recyclerView = findViewById(R.id.recyclerView);
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(SearchActivity.this);
recyclerView.setLayoutManager(layoutManager);
videoAdapter = new VideoAdapter(new ArrayList<>(), 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<VideoList> 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<VideoList>() {
@Override
public void onResponse(@NonNull Call<VideoList> call, @NonNull Response<VideoList> 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<VideoList> 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;
}
}

View File

@ -1,12 +1,15 @@
package net.schueller.peertube.activity; package net.schueller.peertube.activity;
import android.Manifest; import android.Manifest;
import android.app.Activity; import android.app.SearchManager;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.SearchRecentSuggestions;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.bottomnavigation.LabelVisibilityMode;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity; 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.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
//import com.google.android.gms.common.GooglePlayServicesNotAvailableException; //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.model.VideoList;
import net.schueller.peertube.network.GetVideoDataService; import net.schueller.peertube.network.GetVideoDataService;
import net.schueller.peertube.network.RetrofitInstance; import net.schueller.peertube.network.RetrofitInstance;
import net.schueller.peertube.provider.SearchSuggestionsProvider;
import java.util.ArrayList; import java.util.ArrayList;
@ -58,6 +65,10 @@ public class VideoListActivity extends AppCompatActivity {
private int count = 12; private int count = 12;
private String sort = "-createdAt"; private String sort = "-createdAt";
private String filter = ""; private String filter = "";
private String searchQuery = "";
private TextView emptyView;
private RecyclerView recyclerView;
private boolean isLoading = false; private boolean isLoading = false;
@ -124,7 +135,7 @@ public class VideoListActivity extends AppCompatActivity {
BottomNavigationViewEx navigation = findViewById(R.id.navigation); BottomNavigationViewEx navigation = findViewById(R.id.navigation);
navigation.enableAnimation(false); navigation.enableAnimation(false);
navigation.setLabelVisibilityMode(1); // enableShiftingMode navigation.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); // enableShiftingMode
navigation.setItemHorizontalTranslationEnabled(false); // enableItemShiftingMode navigation.setItemHorizontalTranslationEnabled(false); // enableItemShiftingMode
Menu navMenu = navigation.getMenu(); Menu navMenu = navigation.getMenu();
@ -151,16 +162,49 @@ public class VideoListActivity extends AppCompatActivity {
inflater.inflate(R.menu.menu_main, menu); inflater.inflate(R.menu.menu_main, menu);
// Set an icon in the ActionBar // 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( menu.findItem(R.id.action_settings).setIcon(
new IconDrawable(this, FontAwesomeIcons.fa_cog) new IconDrawable(this, FontAwesomeIcons.fa_cog)
.colorRes(R.color.cardview_light_background) .colorRes(R.color.cardview_light_background)
.actionBarSize()); .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; return true;
} }
@ -175,7 +219,6 @@ public class VideoListActivity extends AppCompatActivity {
// action with ID action_refresh was selected // action with ID action_refresh was selected
case R.id.action_search: case R.id.action_search:
//Toast.makeText(this, "Search Selected", Toast.LENGTH_SHORT).show(); //Toast.makeText(this, "Search Selected", Toast.LENGTH_SHORT).show();
onSearchRequested();
return false; return false;
case R.id.action_settings: case R.id.action_settings:
@ -192,9 +235,11 @@ public class VideoListActivity extends AppCompatActivity {
} }
private void createList() { private void createList() {
RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView = findViewById(R.id.recyclerView);
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout); swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
emptyView = findViewById(R.id.empty_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(VideoListActivity.this); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(VideoListActivity.this);
recyclerView.setLayoutManager(layoutManager); recyclerView.setLayoutManager(layoutManager);
@ -246,7 +291,12 @@ public class VideoListActivity extends AppCompatActivity {
GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
Call<VideoList> call = service.getVideosData(start, count, sort, nsfw); Call<VideoList> 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 the URL called*/
Log.d("URL Called", call.request().url() + ""); Log.d("URL Called", call.request().url() + "");
@ -263,6 +313,17 @@ public class VideoListActivity extends AppCompatActivity {
if (response.body() != null) { if (response.body() != null) {
videoAdapter.setData(response.body().getVideoArrayList()); 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; isLoading = false;
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
} }
@ -303,4 +364,37 @@ public class VideoListActivity extends AppCompatActivity {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); 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;
}
} }

View File

@ -3,6 +3,7 @@ package net.schueller.peertube.helper;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.webkit.URLUtil;
import net.schueller.peertube.R; import net.schueller.peertube.R;
@ -10,7 +11,13 @@ public class APIUrlHelper{
public static String getUrl(Context context) { public static String getUrl(Context context) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(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) { public static String getUrlWithVersion(Context context) {

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.schueller.peertube.activity.SearchActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/appbar"
android:layout_weight="1"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout>

View File

@ -18,6 +18,15 @@
layout="@layout/tool_bar" /> layout="@layout/tool_bar" />
</android.support.design.widget.AppBarLayout> </android.support.design.widget.AppBarLayout>
<TextView
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
android:textColor="@color/black"
android:text="@string/no_data_available" />
<android.support.v4.widget.SwipeRefreshLayout <android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -35,6 +44,8 @@
</android.support.v7.widget.RecyclerView> </android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout> </android.support.v4.widget.SwipeRefreshLayout>
<com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx <com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx

View File

@ -8,8 +8,8 @@
android:id="@+id/action_search" android:id="@+id/action_search"
android:orderInCategory="300" android:orderInCategory="300"
android:title="@string/action_bar_title_search" android:title="@string/action_bar_title_search"
app:showAsAction="always" /> app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
<item <item
android:id="@+id/action_settings" android:id="@+id/action_settings"

View File

@ -55,5 +55,6 @@
<string name="pref_title_version">Version</string> <string name="pref_title_version">Version</string>
<string name="search_hint">Search PeerTube</string> <string name="search_hint">Search PeerTube</string>
<string name="title_activity_search">Search</string> <string name="title_activity_search">Search</string>
<string name="no_data_available">No Results</string>
</resources> </resources>