Merge pull request #1623 from TeamNewPipe/refactor_and_bugfix
Refactor and bugfix
This commit is contained in:
commit
ad065e9281
|
@ -49,12 +49,13 @@ ext {
|
|||
icepickLibVersion = '3.2.0'
|
||||
stethoLibVersion = '1.5.0'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2') {
|
||||
exclude module: 'support-annotations'
|
||||
}
|
||||
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:1eff8c5708'
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:fef71aeccc37'
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.mockito:mockito-core:2.8.9'
|
||||
|
|
|
@ -76,10 +76,6 @@
|
|||
android:name=".about.AboutActivity"
|
||||
android:label="@string/title_activity_about"/>
|
||||
|
||||
<activity
|
||||
android:name=".history.HistoryActivity"
|
||||
android:label="@string/title_activity_history"/>
|
||||
|
||||
<service android:name=".local.subscription.services.SubscriptionsImportService"/>
|
||||
<service android:name=".local.subscription.services.SubscriptionsExportService"/>
|
||||
|
||||
|
@ -122,6 +118,7 @@
|
|||
<activity
|
||||
android:name=".ReCaptchaActivity"
|
||||
android:label="@string/reCaptchaActivity"/>
|
||||
<activity android:name=".download.ExtSDDownloadFailedActivity" />
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package org.schabi.newpipe.download;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||
import org.schabi.newpipe.util.ServiceHelper;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
|
||||
public class ExtSDDownloadFailedActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.download_to_sdcard_error_title)
|
||||
.setMessage(R.string.download_to_sdcard_error_message)
|
||||
.setPositiveButton(R.string.yes, (DialogInterface dialogInterface, int i) -> {
|
||||
NewPipeSettings.resetDownloadFolders(this);
|
||||
finish();
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, (DialogInterface dialogInterface, int i) -> {
|
||||
dialogInterface.dismiss();
|
||||
finish();
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
}
|
|
@ -87,12 +87,7 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
|
|||
RxView.clicks(errorButtonRetry)
|
||||
.debounce(300, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<Object>() {
|
||||
@Override
|
||||
public void accept(Object o) throws Exception {
|
||||
onRetryButtonClicked();
|
||||
}
|
||||
});
|
||||
.subscribe(o -> onRetryButtonClicked());
|
||||
}
|
||||
|
||||
protected void onRetryButtonClicked() {
|
||||
|
|
|
@ -1227,10 +1227,10 @@ public class VideoDetailFragment
|
|||
spinnerToolbar.setVisibility(View.GONE);
|
||||
break;
|
||||
default:
|
||||
if(info.getAudioStreams().isEmpty()) detailControlsBackground.setVisibility(View.GONE);
|
||||
if (!info.getVideoStreams().isEmpty()
|
||||
|| !info.getVideoOnlyStreams().isEmpty()) break;
|
||||
|
||||
detailControlsBackground.setVisibility(View.GONE);
|
||||
detailControlsPopup.setVisibility(View.GONE);
|
||||
spinnerToolbar.setVisibility(View.GONE);
|
||||
thumbnailPlayButton.setImageResource(R.drawable.ic_headset_white_24dp);
|
||||
|
|
|
@ -169,38 +169,35 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
|
|||
context.getResources().getString(R.string.share)
|
||||
};
|
||||
|
||||
final DialogInterface.OnClickListener actions = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
final int index = Math.max(infoListAdapter.getItemsList().indexOf(item), 0);
|
||||
switch (i) {
|
||||
case 0:
|
||||
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
|
||||
break;
|
||||
case 1:
|
||||
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
|
||||
break;
|
||||
case 2:
|
||||
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
|
||||
break;
|
||||
case 3:
|
||||
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
|
||||
break;
|
||||
case 4:
|
||||
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
|
||||
break;
|
||||
case 5:
|
||||
if (getFragmentManager() != null) {
|
||||
PlaylistAppendDialog.fromStreamInfoItems(Collections.singletonList(item))
|
||||
.show(getFragmentManager(), TAG);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
shareUrl(item.getName(), item.getUrl());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
final DialogInterface.OnClickListener actions = (DialogInterface dialogInterface, int i) -> {
|
||||
final int index = Math.max(infoListAdapter.getItemsList().indexOf(item), 0);
|
||||
switch (i) {
|
||||
case 0:
|
||||
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
|
||||
break;
|
||||
case 1:
|
||||
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
|
||||
break;
|
||||
case 2:
|
||||
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
|
||||
break;
|
||||
case 3:
|
||||
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
|
||||
break;
|
||||
case 4:
|
||||
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
|
||||
break;
|
||||
case 5:
|
||||
if (getFragmentManager() != null) {
|
||||
PlaylistAppendDialog.fromStreamInfoItems(Collections.singletonList(item))
|
||||
.show(getFragmentManager(), TAG);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
shareUrl(item.getName(), item.getUrl());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -258,12 +255,12 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
|
|||
private static final int BUTTON_DEBOUNCE_INTERVAL = 100;
|
||||
|
||||
private void monitorSubscription(final ChannelInfo info) {
|
||||
final Consumer<Throwable> onError = new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void accept(Throwable throwable) throws Exception {
|
||||
final Consumer<Throwable> onError = (Throwable throwable) -> {
|
||||
animateView(headerSubscribeButton, false, 100);
|
||||
showSnackBarError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(currentInfo.getServiceId()), "Get subscription status", 0);
|
||||
}
|
||||
showSnackBarError(throwable, UserAction.SUBSCRIPTION,
|
||||
NewPipe.getNameOfService(currentInfo.getServiceId()),
|
||||
"Get subscription status",
|
||||
0);
|
||||
};
|
||||
|
||||
final Observable<List<SubscriptionEntity>> observable = subscriptionService.subscriptionTable()
|
||||
|
@ -279,50 +276,38 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
|
|||
// so only update the UI for the latest emission ("sync" the subscribe button's state)
|
||||
.debounce(100, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<List<SubscriptionEntity>>() {
|
||||
@Override
|
||||
public void accept(List<SubscriptionEntity> subscriptionEntities) throws Exception {
|
||||
updateSubscribeButton(!subscriptionEntities.isEmpty());
|
||||
}
|
||||
}, onError));
|
||||
.subscribe((List<SubscriptionEntity> subscriptionEntities) ->
|
||||
updateSubscribeButton(!subscriptionEntities.isEmpty())
|
||||
, onError));
|
||||
|
||||
}
|
||||
|
||||
private Function<Object, Object> mapOnSubscribe(final SubscriptionEntity subscription) {
|
||||
return new Function<Object, Object>() {
|
||||
@Override
|
||||
public Object apply(@NonNull Object o) throws Exception {
|
||||
subscriptionService.subscriptionTable().insert(subscription);
|
||||
return o;
|
||||
}
|
||||
return (@NonNull Object o) -> {
|
||||
subscriptionService.subscriptionTable().insert(subscription);
|
||||
return o;
|
||||
};
|
||||
}
|
||||
|
||||
private Function<Object, Object> mapOnUnsubscribe(final SubscriptionEntity subscription) {
|
||||
return new Function<Object, Object>() {
|
||||
@Override
|
||||
public Object apply(@NonNull Object o) throws Exception {
|
||||
subscriptionService.subscriptionTable().delete(subscription);
|
||||
return o;
|
||||
}
|
||||
return (@NonNull Object o) -> {
|
||||
subscriptionService.subscriptionTable().delete(subscription);
|
||||
return o;
|
||||
};
|
||||
}
|
||||
|
||||
private void updateSubscription(final ChannelInfo info) {
|
||||
if (DEBUG) Log.d(TAG, "updateSubscription() called with: info = [" + info + "]");
|
||||
final Action onComplete = new Action() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
final Action onComplete = () -> {
|
||||
if (DEBUG) Log.d(TAG, "Updated subscription: " + info.getUrl());
|
||||
}
|
||||
};
|
||||
|
||||
final Consumer<Throwable> onError = new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void accept(@NonNull Throwable throwable) throws Exception {
|
||||
onUnrecoverableError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(info.getServiceId()), "Updating Subscription for " + info.getUrl(), R.string.subscription_update_failed);
|
||||
}
|
||||
};
|
||||
final Consumer<Throwable> onError = (@NonNull Throwable throwable) ->
|
||||
onUnrecoverableError(throwable,
|
||||
UserAction.SUBSCRIPTION,
|
||||
NewPipe.getNameOfService(info.getServiceId()),
|
||||
"Updating Subscription for " + info.getUrl(),
|
||||
R.string.subscription_update_failed);
|
||||
|
||||
disposables.add(subscriptionService.updateChannelInfo(info)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
@ -331,19 +316,16 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
|
|||
}
|
||||
|
||||
private Disposable monitorSubscribeButton(final Button subscribeButton, final Function<Object, Object> action) {
|
||||
final Consumer<Object> onNext = new Consumer<Object>() {
|
||||
@Override
|
||||
public void accept(@NonNull Object o) throws Exception {
|
||||
final Consumer<Object> onNext = (@NonNull Object o) -> {
|
||||
if (DEBUG) Log.d(TAG, "Changed subscription status to this channel!");
|
||||
}
|
||||
};
|
||||
|
||||
final Consumer<Throwable> onError = new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void accept(@NonNull Throwable throwable) throws Exception {
|
||||
onUnrecoverableError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(currentInfo.getServiceId()), "Subscription Change", R.string.subscription_change_failed);
|
||||
}
|
||||
};
|
||||
final Consumer<Throwable> onError = (@NonNull Throwable throwable) ->
|
||||
onUnrecoverableError(throwable,
|
||||
UserAction.SUBSCRIPTION,
|
||||
NewPipe.getNameOfService(currentInfo.getServiceId()),
|
||||
"Subscription Change",
|
||||
R.string.subscription_change_failed);
|
||||
|
||||
/* Emit clicks from main thread unto io thread */
|
||||
return RxView.clicks(subscribeButton)
|
||||
|
@ -355,25 +337,25 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
|
|||
}
|
||||
|
||||
private Consumer<List<SubscriptionEntity>> getSubscribeUpdateMonitor(final ChannelInfo info) {
|
||||
return new Consumer<List<SubscriptionEntity>>() {
|
||||
@Override
|
||||
public void accept(List<SubscriptionEntity> subscriptionEntities) throws Exception {
|
||||
if (DEBUG)
|
||||
Log.d(TAG, "subscriptionService.subscriptionTable.doOnNext() called with: subscriptionEntities = [" + subscriptionEntities + "]");
|
||||
if (subscribeButtonMonitor != null) subscribeButtonMonitor.dispose();
|
||||
return (List<SubscriptionEntity> subscriptionEntities) -> {
|
||||
if (DEBUG)
|
||||
Log.d(TAG, "subscriptionService.subscriptionTable.doOnNext() called with: subscriptionEntities = [" + subscriptionEntities + "]");
|
||||
if (subscribeButtonMonitor != null) subscribeButtonMonitor.dispose();
|
||||
|
||||
if (subscriptionEntities.isEmpty()) {
|
||||
if (DEBUG) Log.d(TAG, "No subscription to this channel!");
|
||||
SubscriptionEntity channel = new SubscriptionEntity();
|
||||
channel.setServiceId(info.getServiceId());
|
||||
channel.setUrl(info.getUrl());
|
||||
channel.setData(info.getName(), info.getAvatarUrl(), info.getDescription(), info.getSubscriberCount());
|
||||
subscribeButtonMonitor = monitorSubscribeButton(headerSubscribeButton, mapOnSubscribe(channel));
|
||||
} else {
|
||||
if (DEBUG) Log.d(TAG, "Found subscription to this channel!");
|
||||
final SubscriptionEntity subscription = subscriptionEntities.get(0);
|
||||
subscribeButtonMonitor = monitorSubscribeButton(headerSubscribeButton, mapOnUnsubscribe(subscription));
|
||||
}
|
||||
if (subscriptionEntities.isEmpty()) {
|
||||
if (DEBUG) Log.d(TAG, "No subscription to this channel!");
|
||||
SubscriptionEntity channel = new SubscriptionEntity();
|
||||
channel.setServiceId(info.getServiceId());
|
||||
channel.setUrl(info.getUrl());
|
||||
channel.setData(info.getName(),
|
||||
info.getAvatarUrl(),
|
||||
info.getDescription(),
|
||||
info.getSubscriberCount());
|
||||
subscribeButtonMonitor = monitorSubscribeButton(headerSubscribeButton, mapOnSubscribe(channel));
|
||||
} else {
|
||||
if (DEBUG) Log.d(TAG, "Found subscription to this channel!");
|
||||
final SubscriptionEntity subscription = subscriptionEntities.get(0);
|
||||
subscribeButtonMonitor = monitorSubscribeButton(headerSubscribeButton, mapOnUnsubscribe(subscription));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -491,8 +473,11 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
|
|||
super.handleNextItems(result);
|
||||
|
||||
if (!result.getErrors().isEmpty()) {
|
||||
showSnackBarError(result.getErrors(), UserAction.REQUESTED_CHANNEL, NewPipe.getNameOfService(serviceId),
|
||||
"Get next page of: " + url, R.string.general_error);
|
||||
showSnackBarError(result.getErrors(),
|
||||
UserAction.REQUESTED_CHANNEL,
|
||||
NewPipe.getNameOfService(serviceId),
|
||||
"Get next page of: " + url,
|
||||
R.string.general_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ public class SearchFragment
|
|||
int itemId = 0;
|
||||
boolean isFirstItem = true;
|
||||
final Context c = getContext();
|
||||
for(String filter : service.getSearchQIHFactory().getAvailableContentFilter()) {
|
||||
for(String filter : service.getSearchQHFactory().getAvailableContentFilter()) {
|
||||
menuItemToFilterName.put(itemId, filter);
|
||||
MenuItem item = menu.add(1,
|
||||
itemId++,
|
||||
|
@ -575,8 +575,7 @@ public class SearchFragment
|
|||
.onNext(searchEditText.getText().toString()),
|
||||
throwable -> showSnackBarError(throwable,
|
||||
UserAction.DELETE_FROM_HISTORY, "none",
|
||||
"Deleting item failed", R.string.general_error)
|
||||
);
|
||||
"Deleting item failed", R.string.general_error));
|
||||
disposables.add(onDelete);
|
||||
})
|
||||
.show();
|
||||
|
@ -837,7 +836,10 @@ public class SearchFragment
|
|||
|
||||
@Override
|
||||
public void handleResult(@NonNull SearchInfo result) {
|
||||
if (!result.getErrors().isEmpty()) {
|
||||
final List<Throwable> exceptions = result.getErrors();
|
||||
if (!exceptions.isEmpty()
|
||||
&& !(exceptions.size() == 1
|
||||
&& exceptions.get(0) instanceof SearchExtractor.NothingFoundException)){
|
||||
showSnackBarError(result.getErrors(), UserAction.SEARCHED,
|
||||
NewPipe.getNameOfService(serviceId), searchString, 0);
|
||||
}
|
||||
|
@ -864,6 +866,7 @@ public class SearchFragment
|
|||
showListFooter(false);
|
||||
currentPageUrl = result.getNextPageUrl();
|
||||
infoListAdapter.addInfoItemList(result.getItems());
|
||||
nextPageUrl = result.getNextPageUrl();
|
||||
|
||||
if (!result.getErrors().isEmpty()) {
|
||||
showSnackBarError(result.getErrors(), UserAction.SEARCHED,
|
||||
|
|
|
@ -26,6 +26,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -343,6 +344,7 @@ public final class BackgroundPlayer extends Service {
|
|||
|
||||
if (!shouldUpdateOnProgress) return;
|
||||
resetNotification();
|
||||
if(Build.VERSION.SDK_INT >= 26 /*Oreo*/) updateNotificationThumbnail();
|
||||
if (bigNotRemoteView != null) {
|
||||
bigNotRemoteView.setProgressBar(R.id.notificationProgressBar, duration, currentProgress, false);
|
||||
bigNotRemoteView.setTextViewText(R.id.notificationTime, getTimeString(currentProgress) + " / " + getTimeString(duration));
|
||||
|
|
|
@ -51,6 +51,7 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
|||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
|
||||
import org.schabi.newpipe.BuildConfig;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
|
@ -69,6 +70,7 @@ import org.schabi.newpipe.player.playqueue.PlayQueue;
|
|||
import org.schabi.newpipe.player.playqueue.PlayQueueAdapter;
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
||||
import org.schabi.newpipe.player.resolver.MediaSourceTag;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.SerializedCache;
|
||||
|
||||
|
@ -86,6 +88,7 @@ import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL
|
|||
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION;
|
||||
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK;
|
||||
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT;
|
||||
import static org.schabi.newpipe.report.UserAction.PLAY_STREAM;
|
||||
|
||||
/**
|
||||
* Base for the players, joining the common properties
|
||||
|
@ -96,7 +99,7 @@ import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJ
|
|||
public abstract class BasePlayer implements
|
||||
Player.EventListener, PlaybackListener, ImageLoadingListener {
|
||||
|
||||
public static final boolean DEBUG = true;
|
||||
public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
|
||||
@NonNull public static final String TAG = "BasePlayer";
|
||||
|
||||
@NonNull final protected Context context;
|
||||
|
@ -363,7 +366,10 @@ public abstract class BasePlayer implements
|
|||
try {
|
||||
context.unregisterReceiver(broadcastReceiver);
|
||||
} catch (final IllegalArgumentException unregisteredException) {
|
||||
Log.e(TAG, "Broadcast receiver already unregistered.", unregisteredException);
|
||||
ErrorActivity.reportError(context, unregisteredException, null, null,
|
||||
ErrorActivity.ErrorInfo.make(PLAY_STREAM,
|
||||
"none",
|
||||
"play stream", R.string.general_error));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1001,6 +1007,8 @@ public abstract class BasePlayer implements
|
|||
try {
|
||||
metadata = (MediaSourceTag) simpleExoPlayer.getCurrentTag();
|
||||
} catch (IndexOutOfBoundsException | ClassCastException error) {
|
||||
if(DEBUG) Log.d(TAG, "Could not update metadata: " + error.getMessage());
|
||||
if(DEBUG) error.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1087,6 +1095,9 @@ public abstract class BasePlayer implements
|
|||
return simpleExoPlayer.isCurrentWindowDynamic();
|
||||
} catch (@NonNull IndexOutOfBoundsException ignored) {
|
||||
// Why would this even happen =(
|
||||
// But lets log it anyway. Save is save
|
||||
if(DEBUG) Log.d(TAG, "Could not update metadata: " + ignored.getMessage());
|
||||
if(DEBUG) ignored.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.util.Log;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupMenu;
|
||||
|
@ -562,6 +563,12 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
|||
if (player != null) {
|
||||
progressLiveSync.setClickable(!player.isLiveEdge());
|
||||
}
|
||||
|
||||
// this will make shure progressCurrentTime has the same width as progressEndTime
|
||||
final ViewGroup.LayoutParams endTimeParams = progressEndTime.getLayoutParams();
|
||||
final ViewGroup.LayoutParams currentTimeParams = progressCurrentTime.getLayoutParams();
|
||||
currentTimeParams.width = progressEndTime.getWidth();
|
||||
progressCurrentTime.setLayoutParams(currentTimeParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Log;
|
|||
|
||||
import org.reactivestreams.Subscriber;
|
||||
import org.reactivestreams.Subscription;
|
||||
import org.schabi.newpipe.BuildConfig;
|
||||
import org.schabi.newpipe.player.playqueue.events.AppendEvent;
|
||||
import org.schabi.newpipe.player.playqueue.events.ErrorEvent;
|
||||
import org.schabi.newpipe.player.playqueue.events.InitEvent;
|
||||
|
@ -41,7 +42,7 @@ import io.reactivex.subjects.BehaviorSubject;
|
|||
public abstract class PlayQueue implements Serializable {
|
||||
private final String TAG = "PlayQueue@" + Integer.toHexString(hashCode());
|
||||
|
||||
public static final boolean DEBUG = true;
|
||||
public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
|
||||
|
||||
private ArrayList<PlayQueueItem> backup;
|
||||
private ArrayList<PlayQueueItem> streams;
|
||||
|
|
|
@ -15,7 +15,8 @@ public enum UserAction {
|
|||
REQUESTED_CHANNEL("requested channel"),
|
||||
REQUESTED_PLAYLIST("requested playlist"),
|
||||
REQUESTED_KIOSK("requested kiosk"),
|
||||
DELETE_FROM_HISTORY("delete from history");
|
||||
DELETE_FROM_HISTORY("delete from history"),
|
||||
PLAY_STREAM("Play stream");
|
||||
|
||||
|
||||
private final String message;
|
||||
|
|
|
@ -71,7 +71,7 @@ public class NewPipeSettings {
|
|||
}
|
||||
|
||||
public static File getVideoDownloadFolder(Context context) {
|
||||
return getFolder(context, R.string.download_path_key, Environment.DIRECTORY_MOVIES);
|
||||
return getDir(context, R.string.download_path_key, Environment.DIRECTORY_MOVIES);
|
||||
}
|
||||
|
||||
public static String getVideoDownloadPath(Context context) {
|
||||
|
@ -81,7 +81,7 @@ public class NewPipeSettings {
|
|||
}
|
||||
|
||||
public static File getAudioDownloadFolder(Context context) {
|
||||
return getFolder(context, R.string.download_path_audio_key, Environment.DIRECTORY_MUSIC);
|
||||
return getDir(context, R.string.download_path_audio_key, Environment.DIRECTORY_MUSIC);
|
||||
}
|
||||
|
||||
public static String getAudioDownloadPath(Context context) {
|
||||
|
@ -90,21 +90,37 @@ public class NewPipeSettings {
|
|||
return prefs.getString(key, Environment.DIRECTORY_MUSIC);
|
||||
}
|
||||
|
||||
private static File getFolder(Context context, int keyID, String defaultDirectoryName) {
|
||||
private static File getDir(Context context, int keyID, String defaultDirectoryName) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
final String key = context.getString(keyID);
|
||||
String downloadPath = prefs.getString(key, null);
|
||||
if ((downloadPath != null) && (!downloadPath.isEmpty())) return new File(downloadPath.trim());
|
||||
|
||||
final File folder = getFolder(defaultDirectoryName);
|
||||
final File dir = getDir(defaultDirectoryName);
|
||||
SharedPreferences.Editor spEditor = prefs.edit();
|
||||
spEditor.putString(key, new File(folder, "NewPipe").getAbsolutePath());
|
||||
spEditor.putString(key, getNewPipeChildFolderPathForDir(dir));
|
||||
spEditor.apply();
|
||||
return folder;
|
||||
return dir;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static File getFolder(String defaultDirectoryName) {
|
||||
private static File getDir(String defaultDirectoryName) {
|
||||
return new File(Environment.getExternalStorageDirectory(), defaultDirectoryName);
|
||||
}
|
||||
|
||||
public static void resetDownloadFolders(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
resetDownloadFolder(prefs, context.getString(R.string.download_path_audio_key), Environment.DIRECTORY_MUSIC);
|
||||
resetDownloadFolder(prefs, context.getString(R.string.download_path_key), Environment.DIRECTORY_MOVIES);
|
||||
}
|
||||
|
||||
private static void resetDownloadFolder(SharedPreferences prefs, String key, String defaultDirectoryName) {
|
||||
SharedPreferences.Editor spEditor = prefs.edit();
|
||||
spEditor.putString(key, getNewPipeChildFolderPathForDir(getDir(defaultDirectoryName)));
|
||||
spEditor.apply();
|
||||
}
|
||||
|
||||
private static String getNewPipeChildFolderPathForDir(File dir) {
|
||||
return new File(dir, "NewPipe").getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public final class ExtractorHelper {
|
|||
return Single.fromCallable(() ->
|
||||
SearchInfo.getInfo(NewPipe.getService(serviceId),
|
||||
NewPipe.getService(serviceId)
|
||||
.getSearchQIHFactory()
|
||||
.getSearchQHFactory()
|
||||
.fromQuery(searchString, contentFilter, sortFilter),
|
||||
contentCountry));
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public final class ExtractorHelper {
|
|||
return Single.fromCallable(() ->
|
||||
SearchInfo.getMoreItems(NewPipe.getService(serviceId),
|
||||
NewPipe.getService(serviceId)
|
||||
.getSearchQIHFactory()
|
||||
.getSearchQHFactory()
|
||||
.fromQuery(searchString, contentFilter, sortFilter),
|
||||
contentCountry,
|
||||
pageUrl));
|
||||
|
|
|
@ -31,8 +31,6 @@ import org.schabi.newpipe.extractor.stream.AudioStream;
|
|||
import org.schabi.newpipe.extractor.stream.Stream;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler;
|
||||
import org.schabi.newpipe.fragments.MainFragment;
|
||||
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
||||
import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
package us.shandian.giga.get;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.download.ExtSDDownloadFailedActivity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
@ -23,7 +30,9 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
private static final String TAG = DownloadManagerImpl.class.getSimpleName();
|
||||
private final DownloadDataSource mDownloadDataSource;
|
||||
|
||||
private final ArrayList<DownloadMission> mMissions = new ArrayList<DownloadMission>();
|
||||
private final ArrayList<DownloadMission> mMissions = new ArrayList<>();
|
||||
@NonNull
|
||||
private final Context context;
|
||||
|
||||
/**
|
||||
* Create a new instance
|
||||
|
@ -33,6 +42,13 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
*/
|
||||
public DownloadManagerImpl(Collection<String> searchLocations, DownloadDataSource downloadDataSource) {
|
||||
mDownloadDataSource = downloadDataSource;
|
||||
this.context = null;
|
||||
loadMissions(searchLocations);
|
||||
}
|
||||
|
||||
public DownloadManagerImpl(Collection<String> searchLocations, DownloadDataSource downloadDataSource, Context context) {
|
||||
mDownloadDataSource = downloadDataSource;
|
||||
this.context = context;
|
||||
loadMissions(searchLocations);
|
||||
}
|
||||
|
||||
|
@ -277,10 +293,12 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
|
||||
private class Initializer extends Thread {
|
||||
private DownloadMission mission;
|
||||
private final DownloadMission mission;
|
||||
private final Handler handler;
|
||||
|
||||
public Initializer(DownloadMission mission) {
|
||||
this.mission = mission;
|
||||
this.handler = new Handler();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -335,6 +353,13 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
af.close();
|
||||
|
||||
mission.start();
|
||||
} catch (IOException ie) {
|
||||
if(context == null) throw new RuntimeException(ie);
|
||||
|
||||
if(ie.getMessage().contains("Permission denied")) {
|
||||
handler.post(() ->
|
||||
context.startActivity(new Intent(context, ExtSDDownloadFailedActivity.class)));
|
||||
} else throw new RuntimeException(ie);
|
||||
} catch (Exception e) {
|
||||
// TODO Notify
|
||||
throw new RuntimeException(e);
|
||||
|
|
|
@ -81,7 +81,7 @@ public class DownloadManagerService extends Service {
|
|||
ArrayList<String> paths = new ArrayList<>(2);
|
||||
paths.add(NewPipeSettings.getVideoDownloadPath(this));
|
||||
paths.add(NewPipeSettings.getAudioDownloadPath(this));
|
||||
mManager = new DownloadManagerImpl(paths, mDataSource);
|
||||
mManager = new DownloadManagerImpl(paths, mDataSource, this);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "mManager == null");
|
||||
Log.d(TAG, "Download directory: " + paths);
|
||||
|
|
|
@ -170,6 +170,8 @@
|
|||
<string name="search_history_deleted">Search history deleted.</string>
|
||||
<!-- error strings -->
|
||||
<string name="general_error">Error</string>
|
||||
<string name="download_to_sdcard_error_title">External storage not available.</string>
|
||||
<string name="download_to_sdcard_error_message">Download to external SD Card is not possible yet. Should the download place be reset?</string>
|
||||
<string name="network_error">Network error</string>
|
||||
<string name="could_not_load_thumbnails">Could not load all thumbnails</string>
|
||||
<string name="youtube_signature_decryption_error">Could not decrypt video URL signature</string>
|
||||
|
|
|
@ -6,7 +6,7 @@ buildscript {
|
|||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.3'
|
||||
classpath 'com.android.tools.build:gradle:3.1.4'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
Loading…
Reference in New Issue