diff --git a/.gitignore b/.gitignore
index e0e3fc21b..b1746282e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@
gradle.properties
*~
.weblate
+*.class
diff --git a/CheckTranslations.java b/CheckTranslations.java
new file mode 100644
index 000000000..8b7c2388b
--- /dev/null
+++ b/CheckTranslations.java
@@ -0,0 +1,170 @@
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.regex.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import java.nio.file.Files;
+import java.nio.charset.Charset;
+
+public final class CheckTranslations {
+
+ private static boolean debug = false;
+ private static boolean plurals = false;
+ private static boolean empty = false;
+ private static boolean remove = false;
+ private static int checks = 0;
+ private static int matches = 0;
+ private static int changes = 0;
+ private static Pattern p, pb, pe, e, o;
+
+ /**
+ * Search translated strings.xml files for empty item / plural tags
+ * and remove them.
+ * @param args directories which contain string.xml files (in any subdirectory)
+ * -e option to find all empty string tags
+ * -p option to find all empty plurals and item tags
+ * -r option to remove all occurrences from the files
+ * -d option to see more details
+ */
+ public static void main(String[] args) {
+ if (args.length < 1 || (args[0].equals("-d") && args.length < 2)) {
+ System.out.println("Not enough arguments");
+ return;
+ }
+ for (int i = 0; i < args.length; i++) {
+ switch (args[i]) {
+ case "-d":
+ debug = true;
+ break;
+ case "-p":
+ plurals = true;
+ break;
+ case "-e":
+ empty = true;
+ break;
+ case "-r":
+ remove = true;
+ break;
+ }
+ }
+
+ if (!plurals && !empty) {
+ plurals = true;
+ empty = true;
+ }
+
+ p = Pattern.compile("( |\"/>)");
+ pb = Pattern.compile("()");
+ pe = Pattern.compile("()");
+ e = Pattern.compile("(<\\/string>|\\/>){1})");
+ o = Pattern.compile("(- )[^>]*(<\\/item>)");
+
+ for (int i = 0; i < args.length; i++) {
+ if (!args[i].equals("-d") && !args[i].equals("-p") && !args[i].equals("-e") && !args[i].equals("-r")) {
+ File f = new File(args[i]);
+ if (f.exists() && !f.isDirectory()) {
+ checkFile(f);
+ } else if (f.isDirectory()) {
+ checkFiles(f.listFiles());
+ } else {
+ System.out.println("'" + args[i] + "' does not exist!");
+ }
+ }
+ }
+
+ System.out.println(checks + " files were checked.");
+ System.out.println(matches + " corrupt lines detected.");
+ if (remove) {
+ System.out.println(matches + " corrupt lines removed and " + changes + " lines fixed.");
+ }
+ }
+
+
+ private static void checkFiles(File[] f) {
+ for (int i = 0; i < f.length; i++) {
+ if (f[i].exists() && !f[i].isDirectory()) {
+ if (f[i].toString().contains("strings.xml")) {
+ checkFile(f[i]);
+ }
+ } else if (f[i].isDirectory()) {
+ checkFiles(f[i].listFiles());
+ }
+ }
+ }
+
+ private static void checkFile(File f) {
+ // Do not check our original English strings to cause no unwanted changes
+ // Btw. there should not be empty plural/item tags
+ if (f.toString().contains("values/strings.xml")) {
+ return;
+ }
+ if (debug) System.out.println("Checking " + f.toString());
+ checks++;
+
+
+ List lines = new ArrayList();
+ boolean checkFailed = false;
+ boolean otherDetected = false;
+ boolean inPlurals = false;
+ try (BufferedReader br = new BufferedReader(new FileReader(f))) {
+ String line;
+ int ln = 0;
+ while ((line = br.readLine()) != null) {
+ ln++;
+ if (plurals && p.matcher(line).find()) {
+ matches++;
+ if (debug) System.out.println(" Line " + ln + " was " + ((remove) ? "removed" : "detected") + ": '" + line + "'");
+ checkFailed = true;
+ } else if (empty && e.matcher(line).find()) {
+ matches++;
+ checkFailed = true;
+ if (debug) System.out.println(" Line " + ln + " was " + ((remove) ? "removed" : "detected") + ": '" + line + "'");
+ } else {
+ if (remove) lines.add(line);
+ }
+ }
+ br.close();
+ int pluralsLine = 0;
+ for (int i = 0; i < lines.size(); i++) {
+ if (o.matcher(lines.get(i)).find()) {
+ otherDetected = true;
+ }
+ if (plurals && pb.matcher(lines.get(i)).find()) {
+ inPlurals = true;
+ pluralsLine = i;
+ } else if (plurals && pe.matcher(lines.get(i)).find()) {
+ inPlurals = false;
+ if (!otherDetected) {
+ boolean b = false;
+ check: for(int j = pluralsLine; j < i; j++) {
+ if (lines.get(j).contains("many")) {
+ b = true;
+ pluralsLine = j;
+ break check;
+ }
+ }
+ if (remove && b) {
+ if (debug) System.out.println(" Line " + (pluralsLine + 1) + " was " + ((remove) ? "changed" : "detected") + ": '" + lines.get(pluralsLine) + "'");
+ lines.set(pluralsLine, lines.get(pluralsLine).replace("many", "other"));
+ changes++;
+ checkFailed = true;
+ } else if (debug) {
+ if (debug) System.out.println(" WARNING: Line " + (i + 1) + " - No
- found!");
+ }
+ }
+ otherDetected = false;
+ }
+
+ }
+ if (remove && checkFailed) {
+ Files.write(f.toPath(), lines, Charset.forName("UTF-8"));
+ }
+ } catch (IOException e) {
+ System.out.println(e);
+ }
+ }
+}
+
diff --git a/app/build.gradle b/app/build.gradle
index 50fa6ab12..ef034f98d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,8 +8,8 @@ android {
applicationId "org.schabi.newpipe"
minSdkVersion 15
targetSdkVersion 27
- versionCode 43
- versionName "0.11.2"
+ versionCode 45
+ versionName "0.11.4"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@@ -42,8 +42,8 @@ android {
abortOnError false
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
}
}
@@ -55,7 +55,7 @@ dependencies {
exclude module: 'support-annotations'
}
- implementation 'com.github.TeamNewPipe:NewPipeExtractor:044b8fe32f47e28'
+ implementation 'com.github.TeamNewPipe:NewPipeExtractor:9de63f8c0a170a066'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.10.19'
diff --git a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java
index 2e7089300..fe0b6e907 100644
--- a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java
@@ -18,9 +18,8 @@ public class RouterPopupActivity extends RouterActivity {
@Override
protected void handleUrl(String url) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
- && !PermissionHelper.checkSystemAlertWindowPermission(this)) {
- Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
+ if (!PermissionHelper.isPopupEnabled(this)) {
+ PermissionHelper.showPopupEnablementToast(this);
finish();
return;
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java
index a6c8f5fcc..645049078 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java
@@ -1,6 +1,7 @@
package org.schabi.newpipe.fragments;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
@@ -18,6 +19,7 @@ import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.ReCaptchaActivity;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
+import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper;
@@ -240,4 +242,22 @@ public abstract class BaseStateFragment extends BaseFragment implements ViewC
ErrorActivity.reportError(getContext(), exception, MainActivity.class, rootView, ErrorActivity.ErrorInfo.make(userAction, serviceName, request, errorId));
}
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Utils
+ //////////////////////////////////////////////////////////////////////////*/
+
+
+ protected void openUrlInBrowser(String url) {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ startActivity(Intent.createChooser(intent, activity.getString(R.string.share_dialog_title)));
+ }
+
+ protected void shareUrl(String subject, String url) {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_SUBJECT, subject);
+ intent.putExtra(Intent.EXTRA_TEXT, url);
+ startActivity(Intent.createChooser(intent, getString(R.string.share_dialog_title)));
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index 5b445e813..802389a95 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
@@ -505,7 +505,7 @@ public class VideoDetailFragment extends BaseStateFragment implement
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
- NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
+ NavigationHelper.enqueueOnPopupPlayer(getActivity(), new SinglePlayQueue(item));
break;
default:
break;
@@ -623,24 +623,12 @@ public class VideoDetailFragment extends BaseStateFragment implement
if (DEBUG) Log.d(TAG, "setupActionBarHandler() called with: info = [" + info + "]");
sortedStreamVideosList = new ArrayList<>(ListHelper.getSortedStreamVideosList(activity, info.getVideoStreams(), info.getVideoOnlyStreams(), false));
actionBarHandler.setupStreamList(sortedStreamVideosList, spinnerToolbar);
- actionBarHandler.setOnShareListener(new ActionBarHandler.OnActionListener() {
- @Override
- public void onActionSelected(int selectedStreamId) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_SEND);
- intent.putExtra(Intent.EXTRA_TEXT, info.getUrl());
- intent.setType("text/plain");
- startActivity(Intent.createChooser(intent, activity.getString(R.string.share_dialog_title)));
- }
- });
+ actionBarHandler.setOnShareListener(selectedStreamId -> shareUrl(info.name, info.url));
actionBarHandler.setOnOpenInBrowserListener(new ActionBarHandler.OnActionListener() {
@Override
public void onActionSelected(int selectedStreamId) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(info.getUrl()));
- startActivity(Intent.createChooser(intent, activity.getString(R.string.choose_browser)));
+ openUrlInBrowser(info.getUrl());
}
});
@@ -820,11 +808,8 @@ public class VideoDetailFragment extends BaseStateFragment implement
}
private void openPopupPlayer(final boolean append) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
- Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
- TextView messageView = toast.getView().findViewById(android.R.id.message);
- if (messageView != null) messageView.setGravity(Gravity.CENTER);
- toast.show();
+ if (!PermissionHelper.isPopupEnabled(activity)) {
+ PermissionHelper.showPopupEnablementToast(activity);
return;
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
index 8b20f0122..a09a472a5 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
@@ -1,16 +1,21 @@
package org.schabi.newpipe.fragments.list;
+import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
+import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
+import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
@@ -24,6 +29,7 @@ import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.util.NavigationHelper;
+import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.StateSaver;
import java.util.List;
@@ -192,6 +198,7 @@ public abstract class BaseListFragment extends BaseStateFragment implem
protected void showStreamDialog(final StreamInfoItem item) {
final Context context = getContext();
+ final Activity activity = getActivity();
if (context == null || context.getResources() == null || getActivity() == null) return;
final String[] commands = new String[]{
@@ -207,7 +214,7 @@ public abstract class BaseListFragment extends BaseStateFragment implem
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
- NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
+ NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
default:
break;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
index 7a2c65898..0cc5cabf3 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
@@ -1,10 +1,10 @@
package org.schabi.newpipe.fragments.list.channel;
+import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -12,7 +12,6 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.util.Log;
-import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -23,7 +22,6 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-import android.widget.Toast;
import com.jakewharton.rxbinding2.view.RxView;
@@ -153,6 +151,7 @@ public class ChannelFragment extends BaseListInfoFragment {
@Override
protected void showStreamDialog(final StreamInfoItem item) {
+ final Activity activity = getActivity();
final Context context = getContext();
if (context == null || context.getResources() == null || getActivity() == null) return;
@@ -173,7 +172,7 @@ public class ChannelFragment extends BaseListInfoFragment {
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
- NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
+ NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
@@ -182,7 +181,7 @@ public class ChannelFragment extends BaseListInfoFragment {
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
break;
case 4:
- NavigationHelper.playOnPopupPlayer(context, getPlayQueue(index));
+ NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
break;
default:
break;
@@ -222,18 +221,6 @@ public class ChannelFragment extends BaseListInfoFragment {
}
}
- private void openChannelUriInBrowser() {
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- startActivity(intent);
- }
-
- private void shareChannelUri() {
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_TEXT, url);
- startActivity(Intent.createChooser(intent, getString(R.string.share_dialog_title)));
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -241,10 +228,10 @@ public class ChannelFragment extends BaseListInfoFragment {
openRssFeed();
break;
case R.id.menu_item_openInBrowser:
- openChannelUriInBrowser();
+ openUrlInBrowser(url);
break;
case R.id.menu_item_share: {
- shareChannelUri();
+ shareUrl(name, url);
break;
}
default:
@@ -466,13 +453,6 @@ public class ChannelFragment extends BaseListInfoFragment {
headerPopupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
- Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
- TextView messageView = toast.getView().findViewById(android.R.id.message);
- if (messageView != null) messageView.setGravity(Gravity.CENTER);
- toast.show();
- return;
- }
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue());
}
});
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java
index ad0d0432f..424d28276 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java
@@ -58,14 +58,10 @@ public class KioskFragment extends BaseListInfoFragment {
@State
protected String kioskId = "";
-
/*//////////////////////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////////////////////*/
- private View headerRootLayout;
- private TextView headerTitleView;
-
public static KioskFragment getInstance(int serviceId)
throws ExtractionException {
return getInstance(serviceId, NewPipe.getService(serviceId)
@@ -147,8 +143,8 @@ public class KioskFragment extends BaseListInfoFragment {
public Single loadResult(boolean forceReload) {
String contentCountry = PreferenceManager
.getDefaultSharedPreferences(activity)
- .getString(getString(R.string.search_language_key),
- getString(R.string.default_language_value));
+ .getString(getString(R.string.content_country_key),
+ getString(R.string.default_country_value));
return ExtractorHelper.getKioskInfo(serviceId, url, contentCountry, forceReload);
}
@@ -156,8 +152,8 @@ public class KioskFragment extends BaseListInfoFragment {
public Single loadMoreItemsLogic() {
String contentCountry = PreferenceManager
.getDefaultSharedPreferences(activity)
- .getString(getString(R.string.search_language_key),
- getString(R.string.default_language_value));
+ .getString(getString(R.string.content_country_key),
+ getString(R.string.default_country_value));
return ExtractorHelper.getMoreKioskItems(serviceId, url, currentNextItemsUrl, contentCountry);
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
index 4f87228a5..52eeb337c 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
@@ -1,22 +1,21 @@
package org.schabi.newpipe.fragments.list.playlist;
+import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
-import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
-import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
-import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ListExtractor;
@@ -32,7 +31,6 @@ import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.NavigationHelper;
-import org.schabi.newpipe.util.PermissionHelper;
import io.reactivex.Single;
@@ -98,16 +96,10 @@ public class PlaylistFragment extends BaseListInfoFragment {
infoListAdapter.useMiniItemVariants(true);
}
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]");
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.menu_playlist, menu);
- }
-
@Override
protected void showStreamDialog(final StreamInfoItem item) {
final Context context = getContext();
+ final Activity activity = getActivity();
if (context == null || context.getResources() == null || getActivity() == null) return;
final String[] commands = new String[]{
@@ -127,7 +119,7 @@ public class PlaylistFragment extends BaseListInfoFragment {
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
- NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
+ NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
@@ -136,7 +128,7 @@ public class PlaylistFragment extends BaseListInfoFragment {
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
break;
case 4:
- NavigationHelper.playOnPopupPlayer(context, getPlayQueue(index));
+ NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
break;
default:
break;
@@ -146,6 +138,14 @@ public class PlaylistFragment extends BaseListInfoFragment {
new InfoItemDialog(getActivity(), item, commands, actions).show();
}
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]");
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.menu_playlist, menu);
+ }
+
/*//////////////////////////////////////////////////////////////////////////
// Load and handle
//////////////////////////////////////////////////////////////////////////*/
@@ -160,6 +160,23 @@ public class PlaylistFragment extends BaseListInfoFragment {
return ExtractorHelper.getPlaylistInfo(serviceId, url, forceLoad);
}
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_item_openInBrowser:
+ openUrlInBrowser(url);
+ break;
+ case R.id.menu_item_share: {
+ shareUrl(name, url);
+ break;
+ }
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ return true;
+ }
+
+
/*//////////////////////////////////////////////////////////////////////////
// Contract
//////////////////////////////////////////////////////////////////////////*/
@@ -211,13 +228,6 @@ public class PlaylistFragment extends BaseListInfoFragment {
headerPopupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
- Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
- TextView messageView = toast.getView().findViewById(android.R.id.message);
- if (messageView != null) messageView.setGravity(Gravity.CENTER);
- toast.show();
- return;
- }
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue());
}
});
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
index b30a73455..d6ed2a313 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
@@ -111,7 +111,7 @@ public class SearchFragment extends BaseListFragment> network = ExtractorHelper.suggestionsFor(serviceId, query, searchLanguage).toObservable()
+ final Observable
> network = ExtractorHelper.suggestionsFor(serviceId, query, contentCountry).toObservable()
.map(new Function, List>() {
@Override
public List apply(@io.reactivex.annotations.NonNull List strings) throws Exception {
@@ -731,7 +731,7 @@ public class SearchFragment extends BaseListFragment() {
@@ -755,7 +755,7 @@ public class SearchFragment extends BaseListFragment() {
diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java
index 482f8f803..fd47a7167 100644
--- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java
@@ -65,7 +65,6 @@ public final class BackgroundPlayer extends Service {
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.BackgroundPlayer.CLOSE";
public static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.BackgroundPlayer.PLAY_PAUSE";
- public static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.BackgroundPlayer.OPEN_CONTROLS";
public static final String ACTION_REPEAT = "org.schabi.newpipe.player.BackgroundPlayer.REPEAT";
public static final String ACTION_PLAY_NEXT = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_PLAY_NEXT";
public static final String ACTION_PLAY_PREVIOUS = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_PLAY_PREVIOUS";
@@ -195,11 +194,14 @@ public final class BackgroundPlayer extends Service {
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationStop,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT));
- remoteViews.setOnClickPendingIntent(R.id.notificationContent,
- PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_OPEN_CONTROLS), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationRepeat,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
+ // Starts background player activity -- attempts to unlock lockscreen
+ final Intent intent = NavigationHelper.getBackgroundPlayerActivityIntent(this);
+ remoteViews.setOnClickPendingIntent(R.id.notificationContent,
+ PendingIntent.getActivity(this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+
if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) {
remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_previous);
remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_next);
@@ -393,7 +395,7 @@ public final class BackgroundPlayer extends Service {
if (index < 0 || index >= info.audio_streams.size()) return null;
final AudioStream audio = info.audio_streams.get(index);
- return buildMediaSource(audio.getUrl(), MediaFormat.getSuffixById(audio.format));
+ return buildMediaSource(audio.getUrl(), MediaFormat.getSuffixById(audio.getFormatId()));
}
@Override
@@ -453,7 +455,6 @@ public final class BackgroundPlayer extends Service {
super.setupBroadcastReceiver(intentFilter);
intentFilter.addAction(ACTION_CLOSE);
intentFilter.addAction(ACTION_PLAY_PAUSE);
- intentFilter.addAction(ACTION_OPEN_CONTROLS);
intentFilter.addAction(ACTION_REPEAT);
intentFilter.addAction(ACTION_PLAY_PREVIOUS);
intentFilter.addAction(ACTION_PLAY_NEXT);
@@ -478,9 +479,6 @@ public final class BackgroundPlayer extends Service {
case ACTION_PLAY_PAUSE:
onVideoPlayPause();
break;
- case ACTION_OPEN_CONTROLS:
- NavigationHelper.openBackgroundPlayerControl(getApplicationContext());
- break;
case ACTION_REPEAT:
onRepeatClicked();
break;
diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java
index e5115f2e8..de711f9ac 100644
--- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java
@@ -1,9 +1,12 @@
package org.schabi.newpipe.player;
import android.content.Intent;
+import android.view.MenuItem;
import org.schabi.newpipe.R;
+import static org.schabi.newpipe.player.BackgroundPlayer.ACTION_CLOSE;
+
public final class BackgroundPlayerActivity extends ServicePlayerActivity {
private static final String TAG = "BackgroundPlayerActivity";
@@ -36,4 +39,25 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity {
((BackgroundPlayer.BasePlayerImpl) player).removeActivityListener(this);
}
}
+
+ @Override
+ public int getPlayerOptionMenuResource() {
+ return R.menu.menu_play_queue_bg;
+ }
+
+ @Override
+ public boolean onPlayerOptionSelected(MenuItem item) {
+ if (item.getItemId() == R.id.action_switch_popup) {
+ this.player.setRecovery();
+ getApplicationContext().sendBroadcast(getPlayerShutdownIntent());
+ getApplicationContext().startService(getSwitchIntent(PopupVideoPlayer.class));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Intent getPlayerShutdownIntent() {
+ return new Intent(ACTION_CLOSE);
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java
index e68f56edb..98dd99c3c 100644
--- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java
@@ -78,6 +78,7 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView;
public final class MainVideoPlayer extends Activity {
private static final String TAG = ".MainVideoPlayer";
private static final boolean DEBUG = BasePlayer.DEBUG;
+ private static final String PLAYER_STATE_INTENT = "player_state_intent";
private GestureDetector gestureDetector;
@@ -99,19 +100,41 @@ public final class MainVideoPlayer extends Activity {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) getWindow().setStatusBarColor(Color.BLACK);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
- if (getIntent() == null) {
+ final Intent intent;
+ if (savedInstanceState != null && savedInstanceState.getParcelable(PLAYER_STATE_INTENT) != null) {
+ intent = savedInstanceState.getParcelable(PLAYER_STATE_INTENT);
+ } else {
+ intent = getIntent();
+ }
+
+ if (intent == null) {
Toast.makeText(this, R.string.general_error, Toast.LENGTH_SHORT).show();
finish();
return;
}
-
-
showSystemUi();
setContentView(R.layout.activity_main_player);
playerImpl = new VideoPlayerImpl(this);
playerImpl.setup(findViewById(android.R.id.content));
- playerImpl.handleIntent(getIntent());
+ playerImpl.handleIntent(intent);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ if (this.playerImpl == null) return;
+
+ final Intent intent = NavigationHelper.getPlayerIntent(
+ getApplicationContext(),
+ this.getClass(),
+ this.playerImpl.getPlayQueue(),
+ this.playerImpl.getRepeatMode(),
+ this.playerImpl.getPlaybackSpeed(),
+ this.playerImpl.getPlaybackPitch(),
+ this.playerImpl.getPlaybackQuality()
+ );
+ outState.putParcelable(PLAYER_STATE_INTENT, intent);
}
@Override
@@ -448,12 +471,9 @@ public final class MainVideoPlayer extends Activity {
if (getCurrentState() != STATE_COMPLETED) {
getControlsVisibilityHandler().removeCallbacksAndMessages(null);
- animateView(getControlsRoot(), true, 300, 0, new Runnable() {
- @Override
- public void run() {
- if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) {
- hideControls(300, DEFAULT_CONTROLS_HIDE_TIME);
- }
+ animateView(getControlsRoot(), true, 300, 0, () -> {
+ if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) {
+ hideControls(300, DEFAULT_CONTROLS_HIDE_TIME);
}
});
}
@@ -506,6 +526,7 @@ public final class MainVideoPlayer extends Activity {
private void onScreenRotationClicked() {
if (DEBUG) Log.d(TAG, "onScreenRotationClicked() called");
toggleOrientation();
+ showControlsThenHide();
}
@Override
@@ -561,12 +582,9 @@ public final class MainVideoPlayer extends Activity {
@Override
public void onPlaying() {
super.onPlaying();
- animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, new Runnable() {
- @Override
- public void run() {
- playPauseButton.setImageResource(R.drawable.ic_pause_white);
- animatePlayButtons(true, 200);
- }
+ animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> {
+ playPauseButton.setImageResource(R.drawable.ic_pause_white);
+ animatePlayButtons(true, 200);
});
showSystemUi();
getRootView().setKeepScreenOn(true);
@@ -575,12 +593,9 @@ public final class MainVideoPlayer extends Activity {
@Override
public void onPaused() {
super.onPaused();
- animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, new Runnable() {
- @Override
- public void run() {
- playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
- animatePlayButtons(true, 200);
- }
+ animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> {
+ playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
+ animatePlayButtons(true, 200);
});
showSystemUi();
@@ -598,12 +613,9 @@ public final class MainVideoPlayer extends Activity {
@Override
public void onCompleted() {
showSystemUi();
- animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, new Runnable() {
- @Override
- public void run() {
- playPauseButton.setImageResource(R.drawable.ic_replay_white);
- animatePlayButtons(true, 300);
- }
+ animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, () -> {
+ playPauseButton.setImageResource(R.drawable.ic_replay_white);
+ animatePlayButtons(true, 300);
});
getRootView().setKeepScreenOn(false);
@@ -632,17 +644,10 @@ public final class MainVideoPlayer extends Activity {
public void hideControls(final long duration, long delay) {
if (DEBUG) Log.d(TAG, "hideControls() called with: delay = [" + delay + "]");
getControlsVisibilityHandler().removeCallbacksAndMessages(null);
- getControlsVisibilityHandler().postDelayed(new Runnable() {
- @Override
- public void run() {
- animateView(getControlsRoot(), false, duration, 0, new Runnable() {
- @Override
- public void run() {
- hideSystemUi();
- }
- });
- }
- }, delay);
+ getControlsVisibilityHandler().postDelayed(() ->
+ animateView(getControlsRoot(), false, duration, 0, MainVideoPlayer.this::hideSystemUi),
+ delay
+ );
}
private void updatePlaybackButtons() {
@@ -655,22 +660,19 @@ public final class MainVideoPlayer extends Activity {
private void buildMoreOptionsMenu() {
if (moreOptionsPopupMenu == null) return;
- moreOptionsPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- switch (menuItem.getItemId()) {
- case R.id.toggleOrientation:
- onScreenRotationClicked();
- break;
- case R.id.switchPopup:
- onFullScreenButtonClicked();
- break;
- case R.id.switchBackground:
- onPlayBackgroundButtonClicked();
- break;
- }
- return false;
+ moreOptionsPopupMenu.setOnMenuItemClickListener(menuItem -> {
+ switch (menuItem.getItemId()) {
+ case R.id.toggleOrientation:
+ onScreenRotationClicked();
+ break;
+ case R.id.switchPopup:
+ onFullScreenButtonClicked();
+ break;
+ case R.id.switchBackground:
+ onPlayBackgroundButtonClicked();
+ break;
}
+ return false;
});
}
@@ -692,12 +694,7 @@ public final class MainVideoPlayer extends Activity {
playQueueAdapter.setSelectedListener(getOnSelectedListener());
- itemsListCloseButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onQueueClosed();
- }
- });
+ itemsListCloseButton.setOnClickListener(view -> onQueueClosed());
}
private OnScrollBelowItemsListener getQueueScrollListener() {
diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
index 50a02beec..0f0d8d785 100644
--- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
@@ -66,9 +66,9 @@ import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.player.event.PlayerEventListener;
+import org.schabi.newpipe.player.helper.LockManager;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.old.PlayVideoActivity;
-import org.schabi.newpipe.player.helper.LockManager;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.report.ErrorActivity;
@@ -84,7 +84,6 @@ import java.util.List;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
-import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import static org.schabi.newpipe.player.helper.PlayerHelper.isUsingOldPlayer;
@@ -102,7 +101,6 @@ public final class PopupVideoPlayer extends Service {
private static final int NOTIFICATION_ID = 40028922;
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE";
public static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.PopupVideoPlayer.PLAY_PAUSE";
- public static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.PopupVideoPlayer.OPEN_CONTROLS";
public static final String ACTION_REPEAT = "org.schabi.newpipe.player.PopupVideoPlayer.REPEAT";
private static final String POPUP_SAVED_WIDTH = "popup_saved_width";
@@ -169,17 +167,7 @@ public final class PopupVideoPlayer extends Service {
currentWorker = ExtractorHelper.getStreamInfo(serviceId,url,false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Consumer() {
- @Override
- public void accept(@NonNull StreamInfo info) throws Exception {
- fetcherRunnable.onReceive(info);
- }
- }, new Consumer() {
- @Override
- public void accept(@NonNull Throwable throwable) throws Exception {
- fetcherRunnable.onError(throwable);
- }
- });
+ .subscribe(fetcherRunnable::onReceive, fetcherRunnable::onError);
} else {
playerImpl.setStartedFromNewPipe(true);
playerImpl.handleIntent(intent);
@@ -267,11 +255,14 @@ public final class PopupVideoPlayer extends Service {
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT));
notRemoteView.setOnClickPendingIntent(R.id.notificationStop,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT));
- notRemoteView.setOnClickPendingIntent(R.id.notificationContent,
- PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_OPEN_CONTROLS), PendingIntent.FLAG_UPDATE_CURRENT));
notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
+ // Starts popup player activity -- attempts to unlock lockscreen
+ final Intent intent = NavigationHelper.getPopupPlayerActivityIntent(this);
+ notRemoteView.setOnClickPendingIntent(R.id.notificationContent,
+ PendingIntent.getActivity(this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+
setRepeatModeRemote(notRemoteView, playerImpl.getRepeatMode());
return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
@@ -421,12 +412,7 @@ public final class PopupVideoPlayer extends Service {
super.initViews(rootView);
resizingIndicator = rootView.findViewById(R.id.resizing_indicator);
fullScreenButton = rootView.findViewById(R.id.fullScreenButton);
- fullScreenButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onFullScreenButtonClicked();
- }
- });
+ fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked());
}
@Override
@@ -604,7 +590,6 @@ public final class PopupVideoPlayer extends Service {
if (DEBUG) Log.d(TAG, "setupBroadcastReceiver() called with: intentFilter = [" + intentFilter + "]");
intentFilter.addAction(ACTION_CLOSE);
intentFilter.addAction(ACTION_PLAY_PAUSE);
- intentFilter.addAction(ACTION_OPEN_CONTROLS);
intentFilter.addAction(ACTION_REPEAT);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
@@ -623,9 +608,6 @@ public final class PopupVideoPlayer extends Service {
case ACTION_PLAY_PAUSE:
onVideoPlayPause();
break;
- case ACTION_OPEN_CONTROLS:
- NavigationHelper.openPopupPlayerControl(getApplicationContext());
- break;
case ACTION_REPEAT:
onRepeatClicked();
break;
@@ -899,37 +881,31 @@ public final class PopupVideoPlayer extends Service {
}
private void onReceive(final StreamInfo info) {
- mainHandler.post(new Runnable() {
- @Override
- public void run() {
- final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(),
- PopupVideoPlayer.class, new SinglePlayQueue(info));
- playerImpl.handleIntent(intent);
- }
+ mainHandler.post(() -> {
+ final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(),
+ PopupVideoPlayer.class, new SinglePlayQueue(info));
+ playerImpl.handleIntent(intent);
});
}
private void onError(final Throwable exception) {
if (DEBUG) Log.d(TAG, "onError() called with: exception = [" + exception + "]");
exception.printStackTrace();
- mainHandler.post(new Runnable() {
- @Override
- public void run() {
- if (exception instanceof ReCaptchaException) {
- onReCaptchaException();
- } else if (exception instanceof IOException) {
- Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
- } else if (exception instanceof YoutubeStreamExtractor.GemaException) {
- Toast.makeText(context, R.string.blocked_by_gema, Toast.LENGTH_LONG).show();
- } else if (exception instanceof YoutubeStreamExtractor.LiveStreamException) {
- Toast.makeText(context, R.string.live_streams_not_supported, Toast.LENGTH_LONG).show();
- } else if (exception instanceof ContentNotAvailableException) {
- Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
- } else {
- int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error :
- exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error;
- ErrorActivity.reportError(mainHandler, context, exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId));
- }
+ mainHandler.post(() -> {
+ if (exception instanceof ReCaptchaException) {
+ onReCaptchaException();
+ } else if (exception instanceof IOException) {
+ Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
+ } else if (exception instanceof YoutubeStreamExtractor.GemaException) {
+ Toast.makeText(context, R.string.blocked_by_gema, Toast.LENGTH_LONG).show();
+ } else if (exception instanceof YoutubeStreamExtractor.LiveStreamException) {
+ Toast.makeText(context, R.string.live_streams_not_supported, Toast.LENGTH_LONG).show();
+ } else if (exception instanceof ContentNotAvailableException) {
+ Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
+ } else {
+ int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error :
+ exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error;
+ ErrorActivity.reportError(mainHandler, context, exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId));
}
});
stopSelf();
diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java
index 2230c9c52..44fcdb8dd 100644
--- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java
@@ -1,9 +1,12 @@
package org.schabi.newpipe.player;
import android.content.Intent;
+import android.view.MenuItem;
import org.schabi.newpipe.R;
+import static org.schabi.newpipe.player.PopupVideoPlayer.ACTION_CLOSE;
+
public final class PopupVideoPlayerActivity extends ServicePlayerActivity {
private static final String TAG = "PopupVideoPlayerActivity";
@@ -36,4 +39,25 @@ public final class PopupVideoPlayerActivity extends ServicePlayerActivity {
((PopupVideoPlayer.VideoPlayerImpl) player).removeActivityListener(this);
}
}
+
+ @Override
+ public int getPlayerOptionMenuResource() {
+ return R.menu.menu_play_queue_popup;
+ }
+
+ @Override
+ public boolean onPlayerOptionSelected(MenuItem item) {
+ if (item.getItemId() == R.id.action_switch_background) {
+ this.player.setRecovery();
+ getApplicationContext().sendBroadcast(getPlayerShutdownIntent());
+ getApplicationContext().startService(getSwitchIntent(BackgroundPlayer.class));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Intent getPlayerShutdownIntent() {
+ return new Intent(ACTION_CLOSE);
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
index 37b8920b5..58c117017 100644
--- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
@@ -100,6 +100,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
public abstract void stopPlayerListener();
+ public abstract int getPlayerOptionMenuResource();
+
+ public abstract boolean onPlayerOptionSelected(MenuItem item);
+
+ public abstract Intent getPlayerShutdownIntent();
////////////////////////////////////////////////////////////////////////////
// Activity Lifecycle
////////////////////////////////////////////////////////////////////////////
@@ -134,6 +139,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_play_queue, menu);
+ getMenuInflater().inflate(getPlayerOptionMenuResource(), menu);
return true;
}
@@ -153,8 +159,13 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
case R.id.action_system_audio:
startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS));
return true;
+ case R.id.action_switch_main:
+ this.player.setRecovery();
+ getApplicationContext().sendBroadcast(getPlayerShutdownIntent());
+ getApplicationContext().startActivity(getSwitchIntent(MainVideoPlayer.class));
+ return true;
}
- return super.onOptionsItemSelected(item);
+ return onPlayerOptionSelected(item) || super.onOptionsItemSelected(item);
}
@Override
@@ -163,6 +174,17 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
unbind();
}
+ protected Intent getSwitchIntent(final Class clazz) {
+ return NavigationHelper.getPlayerIntent(
+ getApplicationContext(),
+ clazz,
+ this.player.getPlayQueue(),
+ this.player.getRepeatMode(),
+ this.player.getPlaybackSpeed(),
+ this.player.getPlaybackPitch(),
+ null
+ );
+ }
////////////////////////////////////////////////////////////////////////////
// Service Connection
////////////////////////////////////////////////////////////////////////////
@@ -288,14 +310,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
final float playbackSpeed = BasePlayer.PLAYBACK_SPEEDS[i];
final String formattedSpeed = formatSpeed(playbackSpeed);
final MenuItem item = playbackSpeedPopupMenu.getMenu().add(PLAYBACK_SPEED_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedSpeed);
- item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- if (player == null) return false;
+ item.setOnMenuItemClickListener(menuItem -> {
+ if (player == null) return false;
- player.setPlaybackSpeed(playbackSpeed);
- return true;
- }
+ player.setPlaybackSpeed(playbackSpeed);
+ return true;
});
}
}
@@ -308,14 +327,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
final float playbackPitch = BasePlayer.PLAYBACK_PITCHES[i];
final String formattedPitch = formatPitch(playbackPitch);
final MenuItem item = playbackPitchPopupMenu.getMenu().add(PLAYBACK_PITCH_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedPitch);
- item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- if (player == null) return false;
+ item.setOnMenuItemClickListener(menuItem -> {
+ if (player == null) return false;
- player.setPlaybackPitch(playbackPitch);
- return true;
- }
+ player.setPlaybackPitch(playbackPitch);
+ return true;
});
}
}
@@ -323,24 +339,18 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
private void buildItemPopupMenu(final PlayQueueItem item, final View view) {
final PopupMenu menu = new PopupMenu(this, view);
final MenuItem remove = menu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 0, Menu.NONE, R.string.play_queue_remove);
- remove.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- if (player == null) return false;
+ remove.setOnMenuItemClickListener(menuItem -> {
+ if (player == null) return false;
- final int index = player.getPlayQueue().indexOf(item);
- if (index != -1) player.getPlayQueue().remove(index);
- return true;
- }
+ final int index = player.getPlayQueue().indexOf(item);
+ if (index != -1) player.getPlayQueue().remove(index);
+ return true;
});
final MenuItem detail = menu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 1, Menu.NONE, R.string.play_queue_stream_detail);
- detail.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- onOpenDetail(item.getServiceId(), item.getUrl(), item.getTitle());
- return true;
- }
+ detail.setOnMenuItemClickListener(menuItem -> {
+ onOpenDetail(item.getServiceId(), item.getUrl(), item.getTitle());
+ return true;
});
menu.show();
diff --git a/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java b/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java
index 43e240fbb..06614164f 100644
--- a/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java
@@ -382,7 +382,7 @@ public class ErrorActivity extends AppCompatActivity {
private String getContentLangString() {
return PreferenceManager.getDefaultSharedPreferences(this)
- .getString(this.getString(R.string.search_language_key), "none");
+ .getString(this.getString(R.string.content_country_key), "none");
}
private String getOsString() {
diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
index 5293ff3d6..f31ee0131 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
@@ -57,13 +57,13 @@ public final class ExtractorHelper {
}
}
- public static Single searchFor(final int serviceId, final String query, final int pageNumber, final String searchLanguage, final SearchEngine.Filter filter) {
+ public static Single searchFor(final int serviceId, final String query, final int pageNumber, final String contentCountry, final SearchEngine.Filter filter) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable() {
@Override
public SearchResult call() throws Exception {
return SearchResult.getSearchResult(NewPipe.getService(serviceId).getSearchEngine(),
- query, pageNumber, searchLanguage, filter);
+ query, pageNumber, contentCountry, filter);
}
});
}
@@ -79,12 +79,12 @@ public final class ExtractorHelper {
});
}
- public static Single> suggestionsFor(final int serviceId, final String query, final String searchLanguage) {
+ public static Single> suggestionsFor(final int serviceId, final String query, final String contentCountry) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable>() {
@Override
public List call() throws Exception {
- return NewPipe.getService(serviceId).getSuggestionExtractor().suggestionList(query, searchLanguage);
+ return NewPipe.getService(serviceId).getSuggestionExtractor().suggestionList(query, contentCountry);
}
});
}
@@ -143,7 +143,8 @@ public final class ExtractorHelper {
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable() {
@Override
public KioskInfo call() throws Exception {
- return KioskInfo.getInfo(NewPipe.getService(serviceId), url, toUpperCase(contentCountry));
+ Log.e("---------", contentCountry);
+ return KioskInfo.getInfo(NewPipe.getService(serviceId), url, contentCountry);
}
}));
}
@@ -152,7 +153,7 @@ public final class ExtractorHelper {
return Single.fromCallable(new Callable() {
@Override
public NextItemsResult call() throws Exception {
- return KioskInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl, toUpperCase(contentCountry));
+ return KioskInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl, contentCountry);
}
});
}
@@ -219,16 +220,20 @@ public final class ExtractorHelper {
// as it will cause a infinite loop if it is
Throwable cause, getCause = throwable;
+ // Check if throwable is a subclass of any of the filtered classes
+ final Class throwableClass = throwable.getClass();
for (Class> causesEl : causesToCheck) {
- if (throwable.getClass().isAssignableFrom(causesEl)) {
+ if (causesEl.isAssignableFrom(throwableClass)) {
return true;
}
}
+ // Iteratively checks if the root cause of the throwable is a subclass of the filtered class
while ((cause = throwable.getCause()) != null && getCause != cause) {
getCause = cause;
+ final Class causeClass = cause.getClass();
for (Class> causesEl : causesToCheck) {
- if (cause.getClass().isAssignableFrom(causesEl)) {
+ if (causesEl.isAssignableFrom(causeClass)) {
return true;
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index 4475356fa..3a9125bdf 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -1,7 +1,6 @@
package org.schabi.newpipe.util;
import android.app.Activity;
-import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -21,9 +20,7 @@ import org.schabi.newpipe.download.DownloadActivity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService;
-import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
-import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.fragments.MainFragment;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
@@ -46,8 +43,6 @@ import org.schabi.newpipe.settings.SettingsActivity;
public class NavigationHelper {
public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag";
- public static final int PENDING_INTENT_OPEN_PLAYER_ACTIVITY = 1546;
-
/*//////////////////////////////////////////////////////////////////////////
// Players
//////////////////////////////////////////////////////////////////////////*/
@@ -92,9 +87,13 @@ public class NavigationHelper {
context.startActivity(getPlayerIntent(context, MainVideoPlayer.class, queue));
}
- public static void playOnPopupPlayer(final Context context, final PlayQueue queue) {
- Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
- context.startService(getPlayerIntent(context, PopupVideoPlayer.class, queue));
+ public static void playOnPopupPlayer(final Activity activity, final PlayQueue queue) {
+ if (!PermissionHelper.isPopupEnabled(activity)) {
+ PermissionHelper.showPopupEnablementToast(activity);
+ return;
+ }
+ Toast.makeText(activity, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
+ activity.startService(getPlayerIntent(activity, PopupVideoPlayer.class, queue));
}
public static void playOnBackgroundPlayer(final Context context, final PlayQueue queue) {
@@ -102,9 +101,13 @@ public class NavigationHelper {
context.startService(getPlayerIntent(context, BackgroundPlayer.class, queue));
}
- public static void enqueueOnPopupPlayer(final Context context, final PlayQueue queue) {
- Toast.makeText(context, R.string.popup_playing_append, Toast.LENGTH_SHORT).show();
- context.startService(getPlayerEnqueueIntent(context, PopupVideoPlayer.class, queue));
+ public static void enqueueOnPopupPlayer(final Activity activity, final PlayQueue queue) {
+ if (!PermissionHelper.isPopupEnabled(activity)) {
+ PermissionHelper.showPopupEnablementToast(activity);
+ return;
+ }
+ Toast.makeText(activity, R.string.popup_playing_append, Toast.LENGTH_SHORT).show();
+ activity.startService(getPlayerEnqueueIntent(activity, PopupVideoPlayer.class, queue));
}
public static void enqueueOnBackgroundPlayer(final Context context, final PlayQueue queue) {
@@ -264,34 +267,22 @@ public class NavigationHelper {
return true;
}
- public static void openBackgroundPlayerControl(final Context context) {
- openServicePlayerControl(context, BackgroundPlayerActivity.class);
+ public static Intent getBackgroundPlayerActivityIntent(final Context context) {
+ return getServicePlayerActivityIntent(context, BackgroundPlayerActivity.class);
}
- public static void openPopupPlayerControl(final Context context) {
- openServicePlayerControl(context, PopupVideoPlayerActivity.class);
+ public static Intent getPopupPlayerActivityIntent(final Context context) {
+ return getServicePlayerActivityIntent(context, PopupVideoPlayerActivity.class);
}
- private static void openServicePlayerControl(final Context context, final Class activityClass) {
- Intent intent = getServicePlayerControlIntent(context, activityClass);
- context.startActivity(intent);
- context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
- }
-
- public static Intent getServicePlayerControlIntent(final Context context, final Class activityClass) {
- final Intent intent = new Intent(context, activityClass);
+ private static Intent getServicePlayerActivityIntent(final Context context,
+ final Class activityClass) {
+ Intent intent = new Intent(context, activityClass);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
return intent;
}
-
- public static PendingIntent getServicePlayerControlPendingIntent(final Context context, final Class activityClass) {
- Intent intent = getServicePlayerControlIntent(context, activityClass);
- PendingIntent pIntent = PendingIntent.getActivity(context, PENDING_INTENT_OPEN_PLAYER_ACTIVITY, intent, 0);
- return pIntent;
- }
-
/*//////////////////////////////////////////////////////////////////////////
// Link handling
//////////////////////////////////////////////////////////////////////////*/
diff --git a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java
index a5707ecb2..7cf804401 100644
--- a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java
@@ -11,6 +11,11 @@ import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
+import android.view.Gravity;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.schabi.newpipe.R;
public class PermissionHelper {
public static final int PERMISSION_WRITE_STORAGE = 778;
@@ -92,4 +97,16 @@ public class PermissionHelper {
return false;
}else return true;
}
+
+ public static boolean isPopupEnabled(Activity activity) {
+ return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
+ PermissionHelper.checkSystemAlertWindowPermission(activity);
+ }
+
+ public static void showPopupEnablementToast(Context context) {
+ Toast toast = Toast.makeText(context, R.string.msg_popup_permission, Toast.LENGTH_LONG);
+ TextView messageView = toast.getView().findViewById(android.R.id.message);
+ if (messageView != null) messageView.setGravity(Gravity.CENTER);
+ toast.show();
+ }
}
diff --git a/app/src/main/res/layout/dialog_title.xml b/app/src/main/res/layout/dialog_title.xml
index fa7e155d2..36af65eb3 100644
--- a/app/src/main/res/layout/dialog_title.xml
+++ b/app/src/main/res/layout/dialog_title.xml
@@ -31,10 +31,14 @@
android:layout_below="@+id/itemTitleView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_uploader_text_size"
android:visibility="gone"
tools:visibility="visible"
- tools:text="TYPE" />
+ tools:text="UPLOADER" />
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_play_queue.xml b/app/src/main/res/menu/menu_play_queue.xml
index 8fd0c9b6b..671d46329 100644
--- a/app/src/main/res/menu/menu_play_queue.xml
+++ b/app/src/main/res/menu/menu_play_queue.xml
@@ -17,4 +17,9 @@
android:orderInCategory="996"
android:title="@string/play_queue_audio_settings"
app:showAsAction="never"/>
+
+
diff --git a/app/src/main/res/menu/menu_play_queue_bg.xml b/app/src/main/res/menu/menu_play_queue_bg.xml
new file mode 100644
index 000000000..1a3ed0e5a
--- /dev/null
+++ b/app/src/main/res/menu/menu_play_queue_bg.xml
@@ -0,0 +1,10 @@
+
diff --git a/app/src/main/res/menu/menu_play_queue_popup.xml b/app/src/main/res/menu/menu_play_queue_popup.xml
new file mode 100644
index 000000000..dd5177da9
--- /dev/null
+++ b/app/src/main/res/menu/menu_play_queue_popup.xml
@@ -0,0 +1,10 @@
+
diff --git a/app/src/main/res/menu/menu_videooptions.xml b/app/src/main/res/menu/menu_videooptions.xml
index 2fbde0412..1887ec1dd 100644
--- a/app/src/main/res/menu/menu_videooptions.xml
+++ b/app/src/main/res/menu/menu_videooptions.xml
@@ -6,16 +6,16 @@
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index dab133ce7..6508052a7 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -176,13 +176,13 @@
صفر لا تقم با الإختيار (في بعض اللغات) لأنها ليست \"حالة خاصة\" للأندرويد
- - صفر
- - واحد
- - اثنان
- - قليل
- - كثير
- - أخرى
-
+ - صفر
+ - واحد
+ - اثنان
+ - قليل
+ - كثير
+ - أخرى
+
لاتوجد مشاهدات
لاتوجد فديوهات
@@ -292,4 +292,4 @@
إدراج بقائمة الانتظار على خلفية
إدراج بقائمة الانتظار على المنبثقة
ابدأ هنا على خلفية المصدر
-
+
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 55434038d..961a6fa47 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -204,8 +204,7 @@ otevření ve vyskakovacím okně
- %s odběratel
- %s odběratelé
- - %s odběratelů
-
+ - %s odběratelů
Žádná zhlédnutí
@@ -219,8 +218,7 @@ otevření ve vyskakovacím okně
- %s video
- %s videa
- - %s videí
-
+ - %s videí
Stahování
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index c28a742c8..25aed9cd8 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -178,24 +178,18 @@
- %s עוקב
- %s עוקבים
-
-
אין תצוגות
- תצוגה %s
- %s תצוגות
-
-
אין סרטונים
- סרטון %s
- %s סרטונים
-
-
התחל
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index 1e465458f..e51e71e46 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -128,15 +128,10 @@
- %s prenumeratorius
- %s prenumeratoriai
-
-
- Vaizdo įrašai
-
-
-
Pradėti
@@ -214,9 +209,6 @@
Nėra peržiūrų
- %a peržiūra
-
-
-
Nėra vaizdo įrašų
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index aa3672a36..c04d557e8 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -247,23 +247,18 @@
- %s subskrybent
- %s subskrybentów
- - %s subskrybentów
-
+ - %s subskrybentów
- %s odtworzenie
-
- - %s odtworzeń
-
+ - %s odtworzeń
Brak filmów
- %s film
- %s filmów
-
-
Większość znaków specjalnych
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index a1c979665..eb3a21a81 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -236,24 +236,21 @@
- %s подписчик
- %s подписчика
- - %s подписчиков
-
+ - %s подписчиков
Нет просмотров
- %s просмотр
- %s просмотра
- - %s просмотров
-
+ - %s просмотров
Нет видео
- %s видео
- %s видео
- - %s видео
-
+ - %s видео
Элемент удалён
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index caa0bf6cb..19108686a 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -247,24 +247,21 @@ otvorenie okna na popredí
- %s odberateľ
- %s odberatelia
- - %s odberateľov
-
+ - %s odberateľov
Žiadne zobrazenia
- %s zobrazenie
- %s zobrazenia
- - %s zobrazení
-
+ - %s zobrazení
Žiadne videá
- %s video
- %s videá
- - %s videí
-
+ - %s videí
Položka bola odstránená
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index 0b8a6e0f6..d5c78d4ed 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -100,7 +100,9 @@
show_next_video
show_hold_to_append
en
+ GB
search_language
+ content_country
show_age_restricted_content
use_tor
enable_search_history
@@ -140,7 +142,6 @@
@string/charset_most_special_characters_value
-
- af
@@ -300,4 +301,505 @@
- 日本語
- 한국어
+
+
+
+ - Afghanistan
+ - Aland Islands
+ - Albania
+ - Algeria
+ - American Samoa
+ - Andorra
+ - Angola
+ - Anguilla
+ - Antarctica
+ - Antiguaand Barbuda
+ - Argentina
+ - Armenia
+ - Aruba
+ - Australia
+ - Austria
+ - Azerbaijan
+ - Bahamas
+ - Bahrain
+ - Bangladesh
+ - Barbados
+ - Belarus
+ - Belgium
+ - Belize
+ - Benin
+ - Bermuda
+ - Bhutan
+ - Bolivia
+ - Bosniaand Herzegovina
+ - Botswana
+ - BouvetIsland
+ - Brazil
+ - British Virgin Islands
+ - British Indian Ocean Territory
+ - Brunei Darussalam
+ - Bulgaria
+ - Burkina Faso
+ - Burundi
+ - Cambodia
+ - Cameroon
+ - Canada
+ - CapeVerde
+ - Cayman Islands
+ - Central African Republic
+ - Chad
+ - Chile
+ - China
+ - HongKong, China
+ - Macao,China
+ - Christmas Island
+ - Cocos(Keeling) Islands
+ - Colombia
+ - Comoros
+ - Congo(Brazzaville)
+ - Congo, (Kinshasa)
+ - Cook Islands
+ - CostaRica
+ - Côted'Ivoire
+ - Croatia
+ - Cuba
+ - Cyprus
+ - Czech Republic
+ - Denmark
+ - Djibouti
+ - Dominica
+ - Dominican Republic
+ - Ecuador
+ - Egypt
+ - ElSalvador
+ - EquatorialGuinea
+ - Eritrea
+ - Estonia
+ - Ethiopia
+ - Falkland Islands (Malvinas)
+ - Faroe Islands
+ - Fiji
+ - Finland
+ - France
+ - French Guiana
+ - French Polynesia
+ - French Southern Territories
+ - Gabon
+ - Gambia
+ - Georgia
+ - Germany
+ - Ghana
+ - Gibraltar
+ - Greece
+ - Greenland
+ - Grenada
+ - Guadeloupe
+ - Guam
+ - Guatemala
+ - Guernsey
+ - Guinea
+ - Guinea-Bissau
+ - Guyana
+ - Haiti
+ - Heardand Mcdonald Islands
+ - HolySee (Vatican City State)
+ - Honduras
+ - Hungary
+ - Iceland
+ - India
+ - Indonesia
+ - Iran
+ - Iraq
+ - Ireland
+ - Isleof Man
+ - Israel
+ - Italy
+ - Jamaica
+ - Japan
+ - Jersey
+ - Jordan
+ - Kazakhstan
+ - Kenya
+ - Kiribati
+ - Korea(North)
+ - Korea(South)
+ - Kuwait
+ - Kyrgyzstan
+ - Lao
+ - Latvia
+ - Lebanon
+ - Lesotho
+ - Liberia
+ - Libya
+ - Liechtenstein
+ - Lithuania
+ - Luxembourg
+ - Macedonia
+ - Madagascar
+ - Malawi
+ - Malaysia
+ - Maldives
+ - Mali
+ - Malta
+ - MarshallIslands
+ - Martinique
+ - Mauritania
+ - Mauritius
+ - Mayotte
+ - Mexico
+ - Micronesia
+ - Moldova
+ - Monaco
+ - Mongolia
+ - Montenegro
+ - Montserrat
+ - Morocco
+ - Mozambique
+ - Myanmar
+ - Namibia
+ - Nauru
+ - Nepal
+ - Netherlands
+ - Netherlands Antilles
+ - New Caledonia
+ - New Zealand
+ - Nicaragua
+ - Niger
+ - Nigeria
+ - Niue
+ - Norfolk Island
+ - Northern Mariana Islands
+ - Norway
+ - Oman
+ - Pakistan
+ - Palau
+ - Palestinian Territory
+ - Panama
+ - Papua New Guinea
+ - Paraguay
+ - Peru
+ - Philippines
+ - Pitcairn
+ - Poland
+ - Portugal
+ - PuertoRico
+ - Qatar
+ - Réunion
+ - Romania
+ - Russian Federation
+ - Rwanda
+ - Saint-Barthélemy
+ - Saint Helena
+ - Saint KittsandNevis
+ - SaintLucia
+ - Saint-Martin(Frenchpart)
+ - SaintPierreandMiquelon
+ - Saint Vincentand Grenadines
+ - Samoa
+ - San Marino
+ - Sao Tomeand Principe
+ - SaudiArabia
+ - Senegal
+ - Serbia
+ - Seychelles
+ - SierraLeone
+ - Singapore
+ - Slovakia
+ - Slovenia
+ - SolomonIslands
+ - Somalia
+ - SouthAfrica
+ - South Georgiaandthe South Sandwich Islands
+ - South Sudan
+ - Spain
+ - Sri Lanka
+ - Sudan
+ - Suriname
+ - Svalbardand Jan Mayen Islands
+ - Swaziland
+ - Sweden
+ - Switzerland
+ - Syrian ArabRepublic(Syria)
+ - Taiwan, Republicof China
+ - Tajikistan
+ - Tanzania
+ - Thailand
+ - Timor-Leste
+ - Togo
+ - Tokelau
+ - Tonga
+ - Trinidadand Tobago
+ - Tunisia
+ - Turkey
+ - Turkmenistan
+ - Turksand Caicos Islands
+ - Tuvalu
+ - Uganda
+ - Ukraine
+ - United Arab Emirates
+ - United Kingdom
+ - USA
+ - Minor Outlying Islands
+ - Uruguay
+ - Uzbekistan
+ - Vanuatu
+ - Venezuela (BolivarianRepublic)
+ - VietNam
+ - Virgin Islands,
+ - Wallisand Futuna Islands
+ - Western Sahara
+ - Yemen
+ - Zambia
+ - Zimbabwe
+
+
+
+ - AF
+ - AX
+ - AL
+ - DZ
+ - AS
+ - AD
+ - AO
+ - AI
+ - AQ
+ - AG
+ - AR
+ - AM
+ - AW
+ - AU
+ - AT
+ - AZ
+ - BS
+ - BH
+ - BD
+ - BB
+ - BY
+ - BE
+ - BZ
+ - BJ
+ - BM
+ - BT
+ - BO
+ - BA
+ - BW
+ - BV
+ - BR
+ - VG
+ - IO
+ - BN
+ - BG
+ - BF
+ - BI
+ - KH
+ - CM
+ - CA
+ - CV
+ - KY
+ - CF
+ - TD
+ - CL
+ - CN
+ - HK
+ - MO
+ - CX
+ - CC
+ - CO
+ - KM
+ - CG
+ - CD
+ - CK
+ - CR
+ - CI
+ - HR
+ - CU
+ - CY
+ - CZ
+ - DK
+ - DJ
+ - DM
+ - DO
+ - EC
+ - EG
+ - SV
+ - GQ
+ - ER
+ - EE
+ - ET
+ - FK
+ - FO
+ - FJ
+ - FI
+ - FR
+ - GF
+ - PF
+ - TF
+ - GA
+ - GM
+ - GE
+ - DE
+ - GH
+ - GI
+ - GR
+ - GL
+ - GD
+ - GP
+ - GU
+ - GT
+ - GG
+ - GN
+ - GW
+ - GY
+ - HT
+ - HM
+ - VA
+ - HN
+ - HU
+ - IS
+ - IN
+ - ID
+ - IR
+ - IQ
+ - IE
+ - IM
+ - IL
+ - IT
+ - JM
+ - JP
+ - JE
+ - JO
+ - KZ
+ - KE
+ - KI
+ - KP
+ - KR
+ - KW
+ - KG
+ - LA
+ - LV
+ - LB
+ - LS
+ - LR
+ - LY
+ - LI
+ - LT
+ - LU
+ - MK
+ - MG
+ - MW
+ - MY
+ - MV
+ - ML
+ - MT
+ - MH
+ - MQ
+ - MR
+ - MU
+ - YT
+ - MX
+ - FM
+ - MD
+ - MC
+ - MN
+ - ME
+ - MS
+ - MA
+ - MZ
+ - MM
+ - NA
+ - NR
+ - NP
+ - NL
+ - AN
+ - NC
+ - NZ
+ - NI
+ - NE
+ - NG
+ - NU
+ - NF
+ - MP
+ - NO
+ - OM
+ - PK
+ - PW
+ - PS
+ - PA
+ - PG
+ - PY
+ - PE
+ - PH
+ - PN
+ - PL
+ - PT
+ - PR
+ - QA
+ - RE
+ - RO
+ - RU
+ - RW
+ - BL
+ - SH
+ - KN
+ - LC
+ - MF
+ - PM
+ - VC
+ - WS
+ - SM
+ - ST
+ - SA
+ - SN
+ - RS
+ - SC
+ - SL
+ - SG
+ - SK
+ - SI
+ - SB
+ - SO
+ - ZA
+ - GS
+ - SS
+ - ES
+ - LK
+ - SD
+ - SR
+ - SJ
+ - SZ
+ - SE
+ - CH
+ - SY
+ - TW
+ - TJ
+ - TZ
+ - TH
+ - TL
+ - TG
+ - TK
+ - TO
+ - TT
+ - TN
+ - TR
+ - TM
+ - TC
+ - TV
+ - UG
+ - UA
+ - AE
+ - GB
+ - US
+ - UM
+ - UY
+ - UZ
+ - VU
+ - VE
+ - VN
+ - VI
+ - WF
+ - EH
+ - YE
+ - ZM
+ - ZW
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4b0d64239..16bfcbb1a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -83,6 +83,7 @@
Show Hold to Append Tip
Show tip when background or popup button is pressed on video details page
URL not supported
+ Default content country
Default content language
Player
Behavior
@@ -124,6 +125,11 @@
[Unknown]
+ Toggle Orientation
+ Switch to Background
+ Switch to Popup
+ Switch to Main
+
Error
Network error
diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml
index 11672671e..15088494d 100644
--- a/app/src/main/res/xml/content_settings.xml
+++ b/app/src/main/res/xml/content_settings.xml
@@ -3,6 +3,15 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/content">
+
+
+