Skip to content

Commit 2dd4f8b

Browse files
authored
Merge pull request #7458 from litetex/rework-subscription-import-export-ui
Moved subscription import/export options to (overflow) menu
2 parents b4615f7 + 69f95f4 commit 2dd4f8b

23 files changed

Lines changed: 135 additions & 339 deletions

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/settings/PeertubeInstanceListFragment.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ private void showAddItemDialog(final Context c) {
207207

208208
new AlertDialog.Builder(c)
209209
.setTitle(R.string.peertube_instance_add_title)
210-
.setIcon(R.drawable.place_holder_peertube)
210+
.setIcon(R.drawable.ic_placeholder_peertube)
211211
.setView(dialogBinding.getRoot())
212212
.setNegativeButton(R.string.cancel, null)
213213
.setPositiveButton(R.string.ok, (dialog1, which) -> {
@@ -411,7 +411,7 @@ void bind(final int position, final TabViewHolder holder) {
411411
lastChecked = instanceRB;
412412
}
413413
});
414-
instanceIconView.setImageResource(R.drawable.place_holder_peertube);
414+
instanceIconView.setImageResource(R.drawable.ic_placeholder_peertube);
415415
}
416416

417417
@SuppressLint("ClickableViewAccessibility")

app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,17 @@ private ServiceHelper() { }
3131
public static int getIcon(final int serviceId) {
3232
switch (serviceId) {
3333
case 0:
34-
return R.drawable.place_holder_youtube;
34+
return R.drawable.ic_smart_display;
3535
case 1:
36-
return R.drawable.place_holder_cloud;
36+
return R.drawable.ic_cloud;
3737
case 2:
38-
return R.drawable.place_holder_gadse;
38+
return R.drawable.ic_placeholder_media_ccc;
3939
case 3:
40-
return R.drawable.place_holder_peertube;
40+
return R.drawable.ic_placeholder_peertube;
4141
case 4:
42-
return R.drawable.place_holder_bandcamp;
42+
return R.drawable.ic_placeholder_bandcamp;
4343
default:
44-
return R.drawable.place_holder_circle;
44+
return R.drawable.ic_circle;
4545
}
4646
}
4747

-2.61 KB
Binary file not shown.
-5.2 KB
Binary file not shown.
-3.57 KB
Binary file not shown.
-8.62 KB
Binary file not shown.
-8.14 KB
Binary file not shown.
-1.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)