Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Weblate 2018-01-20 21:31:01 +01:00
commit 3634f68364
27 changed files with 286 additions and 160 deletions

View File

@ -8,8 +8,8 @@ android {
applicationId "org.schabi.newpipe"
minSdkVersion 15
targetSdkVersion 27
versionCode 45
versionName "0.11.4"
versionCode 46
versionName "0.11.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -55,7 +55,7 @@ dependencies {
exclude module: 'support-annotations'
}
implementation 'com.github.TeamNewPipe:NewPipeExtractor:9de63f8c0a170a066'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:1c97da8b51b3610'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.10.19'

View File

@ -28,8 +28,13 @@ import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
@ -45,6 +50,7 @@ import org.schabi.newpipe.database.history.dao.WatchHistoryDAO;
import org.schabi.newpipe.database.history.model.HistoryEntry;
import org.schabi.newpipe.database.history.model.SearchHistoryEntry;
import org.schabi.newpipe.database.history.model.WatchHistoryEntry;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.StreamInfo;
@ -69,6 +75,7 @@ public class MainActivity extends AppCompatActivity implements HistoryListener {
private static final String TAG = "MainActivity";
public static final boolean DEBUG = false;
private SharedPreferences sharedPreferences;
private ActionBarDrawerToggle toggle = null;
/*//////////////////////////////////////////////////////////////////////////
// Activity's LifeCycle
@ -76,7 +83,8 @@ public class MainActivity extends AppCompatActivity implements HistoryListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
if (DEBUG)
Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
ThemeHelper.setTheme(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@ -85,8 +93,59 @@ public class MainActivity extends AppCompatActivity implements HistoryListener {
initFragments();
}
Toolbar toolbar = findViewById(R.id.toolbar);
final Toolbar toolbar = findViewById(R.id.toolbar);
final DrawerLayout drawer = findViewById(R.id.drawer_layout);
final NavigationView drawerItems = findViewById(R.id.navigation);
setSupportActionBar(toolbar);
drawerItems.getMenu().getItem(NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("service", "YouTube"))).setChecked(true);
if (!BuildConfig.BUILD_TYPE.equals("release")) {
toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
toggle.syncState();
drawer.addDrawerListener(toggle);
drawerItems.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
drawerItems.getMenu().getItem(NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("service", "YouTube"))).setChecked(false);
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
editor.putString("service", item.getTitle().toString());
editor.apply();
drawer.closeDrawers();
drawerItems.getMenu().getItem(NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("service", "YouTube"))).setChecked(true);
return true;
}
});
} else {
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
if (toggle != null) {
toggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawer.openDrawer(GravityCompat.START);
}
});
}
}
}
});
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
initHistory();

View File

@ -138,7 +138,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
NavigationHelper.openSearchFragment(getFragmentManager(), 0, "");
NavigationHelper.openSearchFragment(getFragmentManager(), NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("service", "YouTube")), "");
return true;
}
return super.onOptionsItemSelected(item);

View File

@ -342,7 +342,11 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
}
break;
case R.id.detail_thumbnail_root_layout:
openVideoPlayer();
if (currentInfo.video_streams.isEmpty() && currentInfo.video_only_streams.isEmpty()) {
openBackgroundPlayer(false);
} else {
openVideoPlayer();
}
break;
case R.id.detail_title_root_layout:
toggleTitleAndDescription();
@ -1158,6 +1162,13 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
showSnackBarError(info.getErrors(), UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(info.getServiceId()), info.getUrl(), 0);
}
if (info.video_streams.isEmpty() && info.video_only_streams.isEmpty()) {
detailControlsBackground.setVisibility(View.GONE);
detailControlsPopup.setVisibility(View.GONE);
spinnerToolbar.setVisibility(View.GONE);
thumbnailPlayButton.setImageResource(R.drawable.ic_headset_white_24dp);
}
if (autoPlayEnabled) {
openVideoPlayer();
// Only auto play in the first open
@ -1201,4 +1212,4 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
showError(getString(R.string.blocked_by_gema), false, R.drawable.gruese_die_gema);
}
}
}

View File

@ -124,20 +124,12 @@ public abstract class BaseListInfoFragment<I extends ListInfo> extends BaseListF
currentWorker = loadResult(forceLoad)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<I>() {
@Override
public void accept(@NonNull I result) throws Exception {
isLoading.set(false);
currentInfo = result;
currentNextItemsUrl = result.next_streams_url;
handleResult(result);
}
}, new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
onError(throwable);
}
});
.subscribe((@NonNull I result) -> {
isLoading.set(false);
currentInfo = result;
currentNextItemsUrl = result.next_streams_url;
handleResult(result);
}, (@NonNull Throwable throwable) -> onError(throwable));
}
/**
@ -153,18 +145,12 @@ public abstract class BaseListInfoFragment<I extends ListInfo> extends BaseListF
currentWorker = loadMoreItemsLogic()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ListExtractor.NextItemsResult>() {
@Override
public void accept(@io.reactivex.annotations.NonNull ListExtractor.NextItemsResult nextItemsResult) throws Exception {
isLoading.set(false);
handleNextItems(nextItemsResult);
}
}, new Consumer<Throwable>() {
@Override
public void accept(@io.reactivex.annotations.NonNull Throwable throwable) throws Exception {
isLoading.set(false);
onError(throwable);
}
.subscribe((@io.reactivex.annotations.NonNull ListExtractor.NextItemsResult nextItemsResult) -> {
isLoading.set(false);
handleNextItems(nextItemsResult);
}, (@io.reactivex.annotations.NonNull Throwable throwable) -> {
isLoading.set(false);
onError(throwable);
});
}

View File

@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Build;
@ -37,7 +38,6 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
@ -62,6 +62,7 @@ import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.PopupMenuIconHacker;
import org.schabi.newpipe.util.ThemeHelper;
import java.lang.reflect.Field;
@ -326,7 +327,7 @@ public final class MainVideoPlayer extends Activity {
this.playNextButton = rootView.findViewById(R.id.playNextButton);
this.moreOptionsButton = rootView.findViewById(R.id.moreOptionsButton);
this.moreOptionsPopupMenu = new PopupMenu(context, moreOptionsButton);
this.moreOptionsPopupMenu.getMenuInflater().inflate(R.menu.menu_videooptions, moreOptionsPopupMenu.getMenu());
buildMoreOptionsMenu();
titleTextView.setSelected(true);
channelTextView.setSelected(true);
@ -379,7 +380,7 @@ public final class MainVideoPlayer extends Activity {
titleTextView.setText(getVideoTitle());
channelTextView.setText(getUploaderName());
playPauseButton.setImageResource(R.drawable.ic_pause_white);
//playPauseButton.setImageResource(R.drawable.ic_pause_white);
}
@Override
@ -499,25 +500,7 @@ public final class MainVideoPlayer extends Activity {
private void onMoreOptionsClicked() {
if (DEBUG) Log.d(TAG, "onMoreOptionsClicked() called");
buildMoreOptionsMenu();
try {
Field[] fields = moreOptionsPopupMenu.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(moreOptionsPopupMenu);
Class<?> classPopupHelper = Class.forName(menuPopupHelper
.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod(
"setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
moreOptionsPopupMenu.show();
isSomePopupMenuVisible = true;
showControls(300);
@ -659,7 +642,9 @@ public final class MainVideoPlayer extends Activity {
}
private void buildMoreOptionsMenu() {
if (moreOptionsPopupMenu == null) return;
this.moreOptionsPopupMenu.getMenuInflater().inflate(R.menu.menu_videooptions,
moreOptionsPopupMenu.getMenu());
moreOptionsPopupMenu.setOnMenuItemClickListener(menuItem -> {
switch (menuItem.getItemId()) {
case R.id.toggleOrientation:
@ -674,6 +659,22 @@ public final class MainVideoPlayer extends Activity {
}
return false;
});
try {
PopupMenuIconHacker.setShowPopupIcon(moreOptionsPopupMenu);
} catch (Exception e) {
e.printStackTrace();
}
// fix icon theme
if(ThemeHelper.isLightThemeSelected(MainVideoPlayer.this)) {
moreOptionsPopupMenu.getMenu()
.findItem(R.id.toggleOrientation)
.setIcon(R.drawable.ic_screen_rotation_black_24dp);
moreOptionsPopupMenu.getMenu()
.findItem(R.id.switchPopup)
.setIcon(R.drawable.ic_fullscreen_exit_black_24dp);
}
}
private void buildQueue() {

View File

@ -57,105 +57,96 @@ public final class ExtractorHelper {
}
}
public static Single<SearchResult> searchFor(final int serviceId, final String query, final int pageNumber, final String contentCountry, final SearchEngine.Filter filter) {
public static Single<SearchResult> searchFor(final int serviceId,
final String query,
final int pageNumber,
final String contentCountry,
final SearchEngine.Filter filter) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<SearchResult>() {
@Override
public SearchResult call() throws Exception {
return SearchResult.getSearchResult(NewPipe.getService(serviceId).getSearchEngine(),
query, pageNumber, contentCountry, filter);
}
});
return Single.fromCallable(() ->
SearchResult.getSearchResult(NewPipe.getService(serviceId).getSearchEngine(),
query, pageNumber, contentCountry, filter)
);
}
public static Single<NextItemsResult> getMoreSearchItems(final int serviceId, final String query, final int nextPageNumber, final String searchLanguage, final SearchEngine.Filter filter) {
public static Single<NextItemsResult> getMoreSearchItems(final int serviceId,
final String query,
final int nextPageNumber,
final String searchLanguage,
final SearchEngine.Filter filter) {
checkServiceId(serviceId);
return searchFor(serviceId, query, nextPageNumber, searchLanguage, filter)
.map(new Function<SearchResult, NextItemsResult>() {
@Override
public NextItemsResult apply(@NonNull SearchResult searchResult) throws Exception {
return new NextItemsResult(searchResult.resultList, nextPageNumber + "", searchResult.errors);
}
});
.map((@NonNull SearchResult searchResult) ->
new NextItemsResult(searchResult.resultList,
nextPageNumber + "",
searchResult.errors));
}
public static Single<List<String>> suggestionsFor(final int serviceId, final String query, final String contentCountry) {
public static Single<List<String>> suggestionsFor(final int serviceId,
final String query,
final String contentCountry) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<List<String>>() {
@Override
public List<String> call() throws Exception {
return NewPipe.getService(serviceId).getSuggestionExtractor().suggestionList(query, contentCountry);
}
});
return Single.fromCallable(() ->
NewPipe.getService(serviceId)
.getSuggestionExtractor()
.suggestionList(query, contentCountry));
}
public static Single<StreamInfo> getStreamInfo(final int serviceId, final String url, boolean forceLoad) {
public static Single<StreamInfo> getStreamInfo(final int serviceId,
final String url,
boolean forceLoad) {
checkServiceId(serviceId);
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<StreamInfo>() {
@Override
public StreamInfo call() throws Exception {
return StreamInfo.getInfo(NewPipe.getService(serviceId), url);
}
}));
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
StreamInfo.getInfo(NewPipe.getService(serviceId), url)));
}
public static Single<ChannelInfo> getChannelInfo(final int serviceId, final String url, boolean forceLoad) {
public static Single<ChannelInfo> getChannelInfo(final int serviceId,
final String url,
boolean forceLoad) {
checkServiceId(serviceId);
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<ChannelInfo>() {
@Override
public ChannelInfo call() throws Exception {
return ChannelInfo.getInfo(NewPipe.getService(serviceId), url);
}
}));
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
ChannelInfo.getInfo(NewPipe.getService(serviceId), url)));
}
public static Single<NextItemsResult> getMoreChannelItems(final int serviceId, final String url, final String nextStreamsUrl) {
public static Single<NextItemsResult> getMoreChannelItems(final int serviceId,
final String url,
final String nextStreamsUrl) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<NextItemsResult>() {
@Override
public NextItemsResult call() throws Exception {
return ChannelInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl);
}
});
return Single.fromCallable(() ->
ChannelInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl));
}
public static Single<PlaylistInfo> getPlaylistInfo(final int serviceId, final String url, boolean forceLoad) {
public static Single<PlaylistInfo> getPlaylistInfo(final int serviceId,
final String url,
boolean forceLoad) {
checkServiceId(serviceId);
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<PlaylistInfo>() {
@Override
public PlaylistInfo call() throws Exception {
return PlaylistInfo.getInfo(NewPipe.getService(serviceId), url);
}
}));
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
PlaylistInfo.getInfo(NewPipe.getService(serviceId), url)));
}
public static Single<NextItemsResult> getMorePlaylistItems(final int serviceId, final String url, final String nextStreamsUrl) {
public static Single<NextItemsResult> getMorePlaylistItems(final int serviceId,
final String url,
final String nextStreamsUrl) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<NextItemsResult>() {
@Override
public NextItemsResult call() throws Exception {
return PlaylistInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl);
}
});
return Single.fromCallable(() ->
PlaylistInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl));
}
public static Single<KioskInfo> getKioskInfo(final int serviceId, final String url, final String contentCountry, boolean forceLoad) {
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<KioskInfo>() {
@Override
public KioskInfo call() throws Exception {
Log.e("---------", contentCountry);
return KioskInfo.getInfo(NewPipe.getService(serviceId), url, contentCountry);
}
}));
public static Single<KioskInfo> getKioskInfo(final int serviceId,
final String url,
final String contentCountry,
boolean forceLoad) {
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
KioskInfo.getInfo(NewPipe.getService(serviceId), url, contentCountry)));
}
public static Single<NextItemsResult> getMoreKioskItems(final int serviceId, final String url, final String nextStreamsUrl, final String contentCountry) {
return Single.fromCallable(new Callable<NextItemsResult>() {
@Override
public NextItemsResult call() throws Exception {
return KioskInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl, contentCountry);
}
});
public static Single<NextItemsResult> getMoreKioskItems(final int serviceId,
final String url,
final String nextStreamsUrl,
final String contentCountry) {
return Single.fromCallable(() ->
KioskInfo.getMoreItems(NewPipe.getService(serviceId),
url, nextStreamsUrl, contentCountry));
}
/*//////////////////////////////////////////////////////////////////////////
@ -163,24 +154,24 @@ public final class ExtractorHelper {
//////////////////////////////////////////////////////////////////////////*/
/**
* Check if we can load it from the cache (forceLoad parameter), if we can't, load from the network (Single loadFromNetwork)
* Check if we can load it from the cache (forceLoad parameter), if we can't,
* load from the network (Single loadFromNetwork)
* and put the results in the cache.
*/
private static <I extends Info> Single<I> checkCache(boolean forceLoad, int serviceId, String url, Single<I> loadFromNetwork) {
private static <I extends Info> Single<I> checkCache(boolean forceLoad,
int serviceId,
String url,
Single<I> loadFromNetwork) {
checkServiceId(serviceId);
loadFromNetwork = loadFromNetwork.doOnSuccess(new Consumer<I>() {
@Override
public void accept(@NonNull I i) throws Exception {
cache.putInfo(i);
}
});
loadFromNetwork = loadFromNetwork.doOnSuccess((@NonNull I i) -> cache.putInfo(i));
Single<I> load;
if (forceLoad) {
cache.removeInfo(serviceId, url);
load = loadFromNetwork;
} else {
load = Maybe.concat(ExtractorHelper.<I>loadFromCache(serviceId, url), loadFromNetwork.toMaybe())
load = Maybe.concat(ExtractorHelper.<I>loadFromCache(serviceId, url),
loadFromNetwork.toMaybe())
.firstElement() //Take the first valid
.toSingle();
}
@ -193,9 +184,7 @@ public final class ExtractorHelper {
*/
public static <I extends Info> Maybe<I> loadFromCache(final int serviceId, final String url) {
checkServiceId(serviceId);
return Maybe.defer(new Callable<MaybeSource<? extends I>>() {
@Override
public MaybeSource<? extends I> call() throws Exception {
return Maybe.defer(() -> {
//noinspection unchecked
I info = (I) cache.getFromKey(serviceId, url);
if (MainActivity.DEBUG) Log.d(TAG, "loadFromCache() called, info > " + info);
@ -206,8 +195,7 @@ public final class ExtractorHelper {
}
return Maybe.empty();
}
});
});
}
/**
@ -215,7 +203,8 @@ public final class ExtractorHelper {
*
* @see Class#isAssignableFrom(Class)
*/
public static boolean hasAssignableCauseThrowable(Throwable throwable, Class<?>... causesToCheck) {
public static boolean hasAssignableCauseThrowable(Throwable throwable,
Class<?>... causesToCheck) {
// Check if getCause is not the same as cause (the getCause is already the root),
// as it will cause a infinite loop if it is
Throwable cause, getCause = throwable;
@ -270,7 +259,9 @@ public final class ExtractorHelper {
* Check if throwable have Interrupted* exception as one of its causes.
*/
public static boolean isInterruptedCaused(Throwable throwable) {
return ExtractorHelper.hasExactCauseThrowable(throwable, InterruptedIOException.class, InterruptedException.class);
return ExtractorHelper.hasExactCauseThrowable(throwable,
InterruptedIOException.class,
InterruptedException.class);
}
public static String toUpperCase(String value) {

View File

@ -1,4 +1,4 @@
/*
/**
* Copyright 2017 Mauricio Colli <mauriciocolli@outlook.com>
* InfoCache.java is part of NewPipe
*

View File

@ -0,0 +1,48 @@
package org.schabi.newpipe.util;
import android.widget.PopupMenu;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by Christian Schabesberger on 20.01.18.
* Copyright 2018 Christian Schabesberger <chris.schabesberger@mailbox.org>
* PopupMenuIconHacker.java is part of NewPipe
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
public class PopupMenuIconHacker {
public static void setShowPopupIcon(PopupMenu menu) throws Exception {
try {
Field[] fields = menu.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(menu);
Class<?> classPopupHelper = Class.forName(menuPopupHelper
.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod(
"setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception e) {
throw new Exception("Could not make Popup menu show Icons", e);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,18 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
<android.support.v4.widget.DrawerLayout
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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="org.schabi.newpipe.MainActivity">
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
android:orientation="vertical"
tools:context="org.schabi.newpipe.MainActivity">
<FrameLayout
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
<include layout="@layout/toolbar_layout"/>
<include layout="@layout/toolbar_layout" />
</FrameLayout>
</merge>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/drawer_items" />
</android.support.v4.widget.DrawerLayout>

View File

@ -244,7 +244,7 @@
android:clickable="true"
android:focusable="true"
android:scaleType="fitXY"
android:src="?attr/options"
android:src="@drawable/ic_more_vert_white_24dp"
tools:ignore="ContentDescription,RtlHardcoded"/>
</RelativeLayout>

View File

@ -273,7 +273,7 @@
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="@string/controls_background_title"
android:textSize="12sp"/>
android:textSize="12sp" />
</RelativeLayout>
<!--UPLOADER-->

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="@string/youtube" />
<item android:title="@string/soundcloud" />
</menu>

View File

@ -4,17 +4,18 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:icon="@drawable/ic_screen_rotation_white"
android:id="@+id/toggleOrientation"
android:icon="@drawable/ic_screen_rotation_white"
android:title="@string/toggle_orientation"
app:showAsAction="always|withText" />
<item
android:icon="@drawable/ic_fullscreen_exit_white"
android:id="@+id/switchPopup"
android:icon="@drawable/ic_fullscreen_exit_white"
android:title="@string/switch_to_popup"
app:showAsAction="always|withText" />
<item android:icon="?audio"
<item
android:id="@+id/switchBackground"
android:icon="?audio"
android:title="@string/switch_to_background"
app:showAsAction="always|withText" />
</menu>

View File

@ -46,6 +46,13 @@
<item>144p</item>
</string-array>
<string-array name="service_list" translatable="false">
<item>@string/youtube</item>
<item>@string/soundcloud</item>
</string-array>
<string name="service_key" translatable="false">service</string>
<string name="default_service_value" translatable="false">@string/youtube</string>
<string name="video_mp4_key" translatable="false">video_mp4</string>
<string name="video_webm_key" translatable="false">video_webm</string>
<string name="video_3gp_key" translatable="false">video_3gp</string>

View File

@ -84,6 +84,7 @@
<string name="show_hold_to_append_summary">Show tip when background or popup button is pressed on video details page</string>
<string name="url_not_supported_toast">URL not supported</string>
<string name="default_content_country_title">Default content country</string>
<string name="service_title">Service</string>
<string name="search_language_title">Default content language</string>
<string name="settings_category_player_title">Player</string>
<string name="settings_category_player_behavior_title">Behavior</string>
@ -329,4 +330,10 @@
<string name="start_here_on_main">Start Playing Here</string>
<string name="start_here_on_background">Start Here on Background</string>
<string name="start_here_on_popup">Start Here on Popup</string>
<!-- Drawer -->
<string name="drawer_open">Open Drawer</string>
<string name="drawer_close">Close Drawer</string>
<string name="youtube" translatable="false">YouTube</string>
<string name="soundcloud" translatable="false">SoundCloud</string>
</resources>

View File

@ -2,7 +2,6 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/content">
<ListPreference
android:defaultValue="@string/default_country_value"
android:entries="@array/country_names"
@ -38,5 +37,4 @@
android:key="@string/main_page_content_key"
android:title="@string/main_page_content"
android:summary="%s"/>
</PreferenceScreen>