Skip to content

Commit a1f64e4

Browse files
Merge branch 'dev' into Remove_compat_methods
2 parents 23c1fc3 + 2dd4f8b commit a1f64e4

26 files changed

Lines changed: 163 additions & 339 deletions

app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.schabi.newpipe.NewPipeDatabase;
2929
import org.schabi.newpipe.R;
3030
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
31+
import org.schabi.newpipe.database.stream.model.StreamEntity;
3132
import org.schabi.newpipe.databinding.PlaylistControlBinding;
3233
import org.schabi.newpipe.databinding.PlaylistHeaderBinding;
3334
import org.schabi.newpipe.error.ErrorInfo;
@@ -41,6 +42,7 @@
4142
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
4243
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
4344
import org.schabi.newpipe.info_list.dialog.InfoItemDialog;
45+
import org.schabi.newpipe.local.dialog.PlaylistDialog;
4446
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
4547
import org.schabi.newpipe.player.MainPlayer.PlayerType;
4648
import org.schabi.newpipe.player.playqueue.PlayQueue;
@@ -56,6 +58,7 @@
5658
import java.util.List;
5759
import java.util.concurrent.atomic.AtomicBoolean;
5860
import java.util.function.Supplier;
61+
import java.util.stream.Collectors;
5962

6063
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
6164
import io.reactivex.rxjava3.core.Flowable;
@@ -237,6 +240,17 @@ public boolean onOptionsItemSelected(final MenuItem item) {
237240
case R.id.menu_item_bookmark:
238241
onBookmarkClicked();
239242
break;
243+
case R.id.menu_item_append_playlist:
244+
disposables.add(PlaylistDialog.createCorrespondingDialog(
245+
getContext(),
246+
getPlayQueue()
247+
.getStreams()
248+
.stream()
249+
.map(StreamEntity::new)
250+
.collect(Collectors.toList()),
251+
dialog -> dialog.show(getFM(), TAG)
252+
));
253+
break;
240254
default:
241255
return super.onOptionsItemSelected(item);
242256
}

app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
package org.schabi.newpipe.local.subscription
22

33
import android.app.Activity
4-
import android.content.BroadcastReceiver
54
import android.content.Context
65
import android.content.DialogInterface
76
import android.content.Intent
8-
import android.content.IntentFilter
97
import android.os.Bundle
108
import android.os.Parcelable
119
import android.view.LayoutInflater
1210
import android.view.Menu
1311
import android.view.MenuInflater
12+
import android.view.MenuItem
13+
import android.view.SubMenu
1414
import android.view.View
1515
import android.view.ViewGroup
1616
import android.widget.Toast
1717
import androidx.activity.result.ActivityResult
1818
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
19+
import androidx.annotation.StringRes
1920
import androidx.appcompat.app.AlertDialog
2021
import androidx.lifecycle.ViewModelProvider
21-
import androidx.localbroadcastmanager.content.LocalBroadcastManager
2222
import androidx.recyclerview.widget.GridLayoutManager
2323
import com.xwray.groupie.Group
2424
import com.xwray.groupie.GroupAdapter
@@ -34,6 +34,7 @@ import org.schabi.newpipe.databinding.FeedItemCarouselBinding
3434
import org.schabi.newpipe.databinding.FragmentSubscriptionBinding
3535
import org.schabi.newpipe.error.ErrorInfo
3636
import org.schabi.newpipe.error.UserAction
37+
import org.schabi.newpipe.extractor.ServiceList
3738
import org.schabi.newpipe.extractor.channel.ChannelInfoItem
3839
import org.schabi.newpipe.fragments.BaseStateFragment
3940
import org.schabi.newpipe.ktx.animate
@@ -45,20 +46,18 @@ import org.schabi.newpipe.local.subscription.item.EmptyPlaceholderItem
4546
import org.schabi.newpipe.local.subscription.item.FeedGroupAddItem
4647
import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem
4748
import org.schabi.newpipe.local.subscription.item.FeedGroupCarouselItem
48-
import org.schabi.newpipe.local.subscription.item.FeedImportExportItem
4949
import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem
5050
import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem.Companion.PAYLOAD_UPDATE_VISIBILITY_MENU_ITEM
5151
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService
52-
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService.EXPORT_COMPLETE_ACTION
5352
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
54-
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.IMPORT_COMPLETE_ACTION
5553
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE
5654
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE
5755
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
5856
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
5957
import org.schabi.newpipe.streams.io.StoredFileHelper
6058
import org.schabi.newpipe.util.NavigationHelper
6159
import org.schabi.newpipe.util.OnClickGesture
60+
import org.schabi.newpipe.util.ServiceHelper
6261
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels
6362
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
6463
import org.schabi.newpipe.util.external_communication.ShareUtils
@@ -74,12 +73,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
7473
private lateinit var subscriptionManager: SubscriptionManager
7574
private val disposables: CompositeDisposable = CompositeDisposable()
7675

77-
private var subscriptionBroadcastReceiver: BroadcastReceiver? = null
78-
7976
private val groupAdapter = GroupAdapter<GroupieViewHolder<FeedItemCarouselBinding>>()
8077
private val feedGroupsSection = Section()
8178
private var feedGroupsCarousel: FeedGroupCarouselItem? = null
82-
private lateinit var importExportItem: FeedImportExportItem
8379
private lateinit var feedGroupsSortMenuItem: HeaderWithMenuItem
8480
private val subscriptionsSection = Section()
8581

@@ -91,12 +87,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
9187
@State
9288
@JvmField
9389
var itemsListState: Parcelable? = null
90+
9491
@State
9592
@JvmField
9693
var feedGroupsListState: Parcelable? = null
97-
@State
98-
@JvmField
99-
var importExportItemExpandedState: Boolean? = null
10094

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

123-
override fun onResume() {
124-
super.onResume()
125-
setupBroadcastReceiver()
126-
}
127-
128117
override fun onPause() {
129118
super.onPause()
130119
itemsListState = binding.itemsList.layoutManager?.onSaveInstanceState()
131120
feedGroupsListState = feedGroupsCarousel?.onSaveInstanceState()
132-
importExportItemExpandedState = importExportItem.isExpanded
133-
134-
if (subscriptionBroadcastReceiver != null && activity != null) {
135-
LocalBroadcastManager.getInstance(activity).unregisterReceiver(subscriptionBroadcastReceiver!!)
136-
}
137121
}
138122

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

151135
activity.supportActionBar?.setDisplayShowTitleEnabled(true)
152136
activity.supportActionBar?.setTitle(R.string.tab_subscriptions)
137+
138+
buildImportExportMenu(menu)
153139
}
154140

155-
private fun setupBroadcastReceiver() {
156-
if (activity == null) return
141+
private fun buildImportExportMenu(menu: Menu) {
142+
// -- Import --
143+
val importSubMenu = menu.addSubMenu(R.string.import_from)
157144

158-
if (subscriptionBroadcastReceiver != null) {
159-
LocalBroadcastManager.getInstance(activity).unregisterReceiver(subscriptionBroadcastReceiver!!)
160-
}
145+
addMenuItemToSubmenu(importSubMenu, R.string.previous_export) { onImportPreviousSelected() }
146+
.setIcon(R.drawable.ic_backup)
161147

162-
val filters = IntentFilter()
163-
filters.addAction(EXPORT_COMPLETE_ACTION)
164-
filters.addAction(IMPORT_COMPLETE_ACTION)
165-
subscriptionBroadcastReceiver = object : BroadcastReceiver() {
166-
override fun onReceive(context: Context, intent: Intent) {
167-
_binding?.itemsList?.post {
168-
importExportItem.isExpanded = false
169-
importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS)
170-
}
148+
for (service in ServiceList.all()) {
149+
val subscriptionExtractor = service.subscriptionExtractor ?: continue
150+
151+
val supportedSources = subscriptionExtractor.supportedSources
152+
if (supportedSources.isEmpty()) continue
153+
154+
addMenuItemToSubmenu(importSubMenu, service.serviceInfo.name) {
155+
onImportFromServiceSelected(service.serviceId)
171156
}
157+
.setIcon(ServiceHelper.getIcon(service.serviceId))
172158
}
173159

174-
LocalBroadcastManager.getInstance(activity).registerReceiver(subscriptionBroadcastReceiver!!, filters)
160+
// -- Export --
161+
val exportSubMenu = menu.addSubMenu(R.string.export_to)
162+
163+
addMenuItemToSubmenu(exportSubMenu, R.string.file) { onExportSelected() }
164+
.setIcon(R.drawable.ic_save)
165+
}
166+
167+
private fun addMenuItemToSubmenu(
168+
subMenu: SubMenu,
169+
@StringRes title: Int,
170+
onClick: Runnable
171+
): MenuItem {
172+
return setClickListenerToMenuItem(subMenu.add(title), onClick)
173+
}
174+
175+
private fun addMenuItemToSubmenu(
176+
subMenu: SubMenu,
177+
title: String,
178+
onClick: Runnable
179+
): MenuItem {
180+
return setClickListenerToMenuItem(subMenu.add(title), onClick)
181+
}
182+
183+
private fun setClickListenerToMenuItem(
184+
menuItem: MenuItem,
185+
onClick: Runnable
186+
): MenuItem {
187+
menuItem.setOnMenuItemClickListener { _ ->
188+
onClick.run()
189+
true
190+
}
191+
return menuItem
175192
}
176193

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

266-
importExportItem = FeedImportExportItem(
267-
{ onImportPreviousSelected() },
268-
{ onImportFromServiceSelected(it) },
269-
{ onExportSelected() },
270-
importExportItemExpandedState ?: false
283+
groupAdapter.add(
284+
Section(
285+
HeaderWithMenuItem(
286+
getString(R.string.tab_subscriptions)
287+
),
288+
listOf(subscriptionsSection)
289+
)
271290
)
272-
groupAdapter.add(Section(importExportItem, listOf(subscriptionsSection)))
273291
}
274292

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

374-
if (result.subscriptions.isEmpty() && importExportItemExpandedState == null) {
375-
binding.itemsList.post {
376-
importExportItem.isExpanded = true
377-
importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS)
378-
}
379-
}
380-
381392
if (itemsListState != null) {
382393
binding.itemsList.layoutManager?.onRestoreInstanceState(itemsListState)
383394
itemsListState = null

app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt

Lines changed: 0 additions & 122 deletions
This file was deleted.

app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@ public void onScroll(@NonNull final MainPlayer.PlayerType playerType,
126126
}
127127

128128
private void onScrollMainVolume(final float distanceX, final float distanceY) {
129+
// If we just started sliding, change the progress bar to match the system volume
130+
if (player.getVolumeRelativeLayout().getVisibility() != View.VISIBLE) {
131+
final float volumePercent = player
132+
.getAudioReactor().getVolume() / (float) maxVolume;
133+
player.getVolumeProgressBar().setProgress(
134+
(int) (volumePercent * player.getMaxGestureLength()));
135+
}
136+
129137
player.getVolumeProgressBar().incrementProgressBy((int) distanceY);
130138
final float currentProgressPercent = (float) player
131139
.getVolumeProgressBar().getProgress() / player.getMaxGestureLength();

0 commit comments

Comments
 (0)