Skip to content

Commit

Permalink
Merge branch 'TeamNewPipe:dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
notaLonelyDay authored May 13, 2022
2 parents 32da377 + 2dd4f8b commit 9b32880
Show file tree
Hide file tree
Showing 44 changed files with 354 additions and 364 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<p align="center"><a href="https://newpipe.net">Website</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">Press</a></p>
<hr>

*Read this in other languages: [English](README.md), [Español](doc/README.es.md), [한국어](doc/README.ko.md), [Soomaali](doc/README.so.md), [Português Brasil](doc/README.pt_BR.md), [Polski](doc/README.pl.md), [日本語](doc/README.ja.md), [Română](doc/README.ro.md), [Türkçe](doc/README.tr.md), [正體中文](doc/README.zh_TW.md).*
*Read this in other languages: [English](README.md), [Español](doc/README.es.md), [हिन्दी](doc/README.hi.md), [한국어](doc/README.ko.md), [Soomaali](doc/README.so.md), [Português Brasil](doc/README.pt_BR.md), [Polski](doc/README.pl.md), [日本語](doc/README.ja.md), [Română](doc/README.ro.md), [Türkçe](doc/README.tr.md), [正體中文](doc/README.zh_TW.md).*

<b>WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OPEN AN ISSUE VIA OUR GITHUB REPOSITORY.</b>

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/org/schabi/newpipe/RouterActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ThemeHelper;
Expand Down Expand Up @@ -127,8 +128,10 @@ protected void onCreate(final Bundle savedInstanceState) {
}
}

ThemeHelper.setDayNightMode(this);
setTheme(ThemeHelper.isLightThemeSelected(this)
? R.style.RouterActivityThemeLight : R.style.RouterActivityThemeDark);
Localization.assureCorrectAppLanguage(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public StreamHistoryEntity(final long streamUid, @NonNull final OffsetDateTime a

@Ignore
public StreamHistoryEntity(final long streamUid, @NonNull final OffsetDateTime accessDate) {
this(streamUid, accessDate, 1);
this(streamUid, accessDate, 0); // start with 0 views (adding views will be done elsewhere)
}

public long getStreamUid() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public class ChannelFragment extends BaseListInfoFragment<StreamInfoItem, Channe
private final CompositeDisposable disposables = new CompositeDisposable();
private Disposable subscribeButtonMonitor;

private boolean channelContentNotSupported = false;

/*//////////////////////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -130,6 +132,7 @@ public View onCreateView(@NonNull final LayoutInflater inflater,
public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) {
super.onViewCreated(rootView, savedInstanceState);
channelBinding = FragmentChannelBinding.bind(rootView);
showContentNotSupportedIfNeeded();
}

@Override
Expand Down Expand Up @@ -524,9 +527,12 @@ public void handleResult(@NonNull final ChannelInfo result) {
playlistControlBinding.getRoot().setVisibility(View.GONE);
}

channelContentNotSupported = false;
for (final Throwable throwable : result.getErrors()) {
if (throwable instanceof ContentNotSupportedException) {
showContentNotSupported();
channelContentNotSupported = true;
showContentNotSupportedIfNeeded();
break;
}
}

Expand Down Expand Up @@ -558,7 +564,13 @@ public void handleResult(@NonNull final ChannelInfo result) {
});
}

private void showContentNotSupported() {
private void showContentNotSupportedIfNeeded() {
// channelBinding might not be initialized when handleResult() is called
// (e.g. after rotating the screen, #6696)
if (!channelContentNotSupported || channelBinding == null) {
return;
}

channelBinding.errorContentNotSupported.setVisibility(View.VISIBLE);
channelBinding.channelKaomoji.setText("(︶︹︺)");
channelBinding.channelKaomoji.setTextSize(TypedValue.COMPLEX_UNIT_SP, 45f);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.PlaylistControlBinding;
import org.schabi.newpipe.databinding.PlaylistHeaderBinding;
import org.schabi.newpipe.error.ErrorInfo;
Expand All @@ -41,6 +42,7 @@
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.info_list.dialog.InfoItemDialog;
import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
import org.schabi.newpipe.player.MainPlayer.PlayerType;
import org.schabi.newpipe.player.playqueue.PlayQueue;
Expand All @@ -56,6 +58,7 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Flowable;
Expand Down Expand Up @@ -237,6 +240,17 @@ public boolean onOptionsItemSelected(final MenuItem item) {
case R.id.menu_item_bookmark:
onBookmarkClicked();
break;
case R.id.menu_item_append_playlist:
disposables.add(PlaylistDialog.createCorrespondingDialog(
getContext(),
getPlayQueue()
.getStreams()
.stream()
.map(StreamEntity::new)
.collect(Collectors.toList()),
dialog -> dialog.show(getFM(), TAG)
));
break;
default:
return super.onOptionsItemSelected(item);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,11 @@ public void removeWatchedStreams(final boolean removePartiallyWatched) {
final PlaylistStreamEntry playlistItem = playlistIter.next();
final int indexInHistory = Collections.binarySearch(historyStreamIds,
playlistItem.getStreamId());
final StreamStateEntity streamStateEntity = streamStatesIter.next();
final long duration = playlistItem.toStreamInfoItem().getDuration();

final boolean hasState = streamStatesIter.next() != null;
if (indexInHistory < 0 || hasState) {
if (indexInHistory < 0 || (streamStateEntity != null
&& !streamStateEntity.isFinished(duration))) {
notWatchedItems.add(playlistItem);
} else if (!thumbnailVideoRemoved
&& playlistManager.getPlaylistThumbnail(playlistId)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package org.schabi.newpipe.local.subscription

import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.SubMenu
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModelProvider
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.recyclerview.widget.GridLayoutManager
import com.xwray.groupie.Group
import com.xwray.groupie.GroupAdapter
Expand All @@ -34,6 +34,7 @@ import org.schabi.newpipe.databinding.FeedItemCarouselBinding
import org.schabi.newpipe.databinding.FragmentSubscriptionBinding
import org.schabi.newpipe.error.ErrorInfo
import org.schabi.newpipe.error.UserAction
import org.schabi.newpipe.extractor.ServiceList
import org.schabi.newpipe.extractor.channel.ChannelInfoItem
import org.schabi.newpipe.fragments.BaseStateFragment
import org.schabi.newpipe.ktx.animate
Expand All @@ -45,20 +46,18 @@ import org.schabi.newpipe.local.subscription.item.EmptyPlaceholderItem
import org.schabi.newpipe.local.subscription.item.FeedGroupAddItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCarouselItem
import org.schabi.newpipe.local.subscription.item.FeedImportExportItem
import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem
import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem.Companion.PAYLOAD_UPDATE_VISIBILITY_MENU_ITEM
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService.EXPORT_COMPLETE_ACTION
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.IMPORT_COMPLETE_ACTION
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
import org.schabi.newpipe.streams.io.StoredFileHelper
import org.schabi.newpipe.util.NavigationHelper
import org.schabi.newpipe.util.OnClickGesture
import org.schabi.newpipe.util.ServiceHelper
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
import org.schabi.newpipe.util.external_communication.ShareUtils
Expand All @@ -74,12 +73,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private lateinit var subscriptionManager: SubscriptionManager
private val disposables: CompositeDisposable = CompositeDisposable()

private var subscriptionBroadcastReceiver: BroadcastReceiver? = null

private val groupAdapter = GroupAdapter<GroupieViewHolder<FeedItemCarouselBinding>>()
private val feedGroupsSection = Section()
private var feedGroupsCarousel: FeedGroupCarouselItem? = null
private lateinit var importExportItem: FeedImportExportItem
private lateinit var feedGroupsSortMenuItem: HeaderWithMenuItem
private val subscriptionsSection = Section()

Expand All @@ -91,12 +87,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
@State
@JvmField
var itemsListState: Parcelable? = null

@State
@JvmField
var feedGroupsListState: Parcelable? = null
@State
@JvmField
var importExportItemExpandedState: Boolean? = null

init {
setHasOptionsMenu(true)
Expand All @@ -120,20 +114,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
return inflater.inflate(R.layout.fragment_subscription, container, false)
}

override fun onResume() {
super.onResume()
setupBroadcastReceiver()
}

override fun onPause() {
super.onPause()
itemsListState = binding.itemsList.layoutManager?.onSaveInstanceState()
feedGroupsListState = feedGroupsCarousel?.onSaveInstanceState()
importExportItemExpandedState = importExportItem.isExpanded

if (subscriptionBroadcastReceiver != null && activity != null) {
LocalBroadcastManager.getInstance(activity).unregisterReceiver(subscriptionBroadcastReceiver!!)
}
}

override fun onDestroy() {
Expand All @@ -150,28 +134,61 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {

activity.supportActionBar?.setDisplayShowTitleEnabled(true)
activity.supportActionBar?.setTitle(R.string.tab_subscriptions)

buildImportExportMenu(menu)
}

private fun setupBroadcastReceiver() {
if (activity == null) return
private fun buildImportExportMenu(menu: Menu) {
// -- Import --
val importSubMenu = menu.addSubMenu(R.string.import_from)

if (subscriptionBroadcastReceiver != null) {
LocalBroadcastManager.getInstance(activity).unregisterReceiver(subscriptionBroadcastReceiver!!)
}
addMenuItemToSubmenu(importSubMenu, R.string.previous_export) { onImportPreviousSelected() }
.setIcon(R.drawable.ic_backup)

val filters = IntentFilter()
filters.addAction(EXPORT_COMPLETE_ACTION)
filters.addAction(IMPORT_COMPLETE_ACTION)
subscriptionBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
_binding?.itemsList?.post {
importExportItem.isExpanded = false
importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS)
}
for (service in ServiceList.all()) {
val subscriptionExtractor = service.subscriptionExtractor ?: continue

val supportedSources = subscriptionExtractor.supportedSources
if (supportedSources.isEmpty()) continue

addMenuItemToSubmenu(importSubMenu, service.serviceInfo.name) {
onImportFromServiceSelected(service.serviceId)
}
.setIcon(ServiceHelper.getIcon(service.serviceId))
}

LocalBroadcastManager.getInstance(activity).registerReceiver(subscriptionBroadcastReceiver!!, filters)
// -- Export --
val exportSubMenu = menu.addSubMenu(R.string.export_to)

addMenuItemToSubmenu(exportSubMenu, R.string.file) { onExportSelected() }
.setIcon(R.drawable.ic_save)
}

private fun addMenuItemToSubmenu(
subMenu: SubMenu,
@StringRes title: Int,
onClick: Runnable
): MenuItem {
return setClickListenerToMenuItem(subMenu.add(title), onClick)
}

private fun addMenuItemToSubmenu(
subMenu: SubMenu,
title: String,
onClick: Runnable
): MenuItem {
return setClickListenerToMenuItem(subMenu.add(title), onClick)
}

private fun setClickListenerToMenuItem(
menuItem: MenuItem,
onClick: Runnable
): MenuItem {
menuItem.setOnMenuItemClickListener { _ ->
onClick.run()
true
}
return menuItem
}

private fun onImportFromServiceSelected(serviceId: Int) {
Expand Down Expand Up @@ -263,13 +280,14 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
subscriptionsSection.setPlaceholder(EmptyPlaceholderItem())
subscriptionsSection.setHideWhenEmpty(true)

importExportItem = FeedImportExportItem(
{ onImportPreviousSelected() },
{ onImportFromServiceSelected(it) },
{ onExportSelected() },
importExportItemExpandedState ?: false
groupAdapter.add(
Section(
HeaderWithMenuItem(
getString(R.string.tab_subscriptions)
),
listOf(subscriptionsSection)
)
)
groupAdapter.add(Section(importExportItem, listOf(subscriptionsSection)))
}

override fun initViews(rootView: View, savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -371,13 +389,6 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
subscriptionsSection.update(result.subscriptions)
subscriptionsSection.setHideWhenEmpty(false)

if (result.subscriptions.isEmpty() && importExportItemExpandedState == null) {
binding.itemsList.post {
importExportItem.isExpanded = true
importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS)
}
}

if (itemsListState != null) {
binding.itemsList.layoutManager?.onRestoreInstanceState(itemsListState)
itemsListState = null
Expand Down
Loading

0 comments on commit 9b32880

Please sign in to comment.