1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-12-23 00:20:32 +00:00

Merge pull request #7458 from litetex/rework-subscription-import-export-ui

Moved subscription import/export options to (overflow) menu
This commit is contained in:
Stypox 2022-05-12 13:03:12 +02:00 committed by GitHub
commit 2dd4f8b04a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 135 additions and 339 deletions

View File

@ -1,24 +1,24 @@
package org.schabi.newpipe.local.subscription package org.schabi.newpipe.local.subscription
import android.app.Activity import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem
import android.view.SubMenu
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.xwray.groupie.Group import com.xwray.groupie.Group
import com.xwray.groupie.GroupAdapter import com.xwray.groupie.GroupAdapter
@ -34,6 +34,7 @@ import org.schabi.newpipe.databinding.FeedItemCarouselBinding
import org.schabi.newpipe.databinding.FragmentSubscriptionBinding import org.schabi.newpipe.databinding.FragmentSubscriptionBinding
import org.schabi.newpipe.error.ErrorInfo import org.schabi.newpipe.error.ErrorInfo
import org.schabi.newpipe.error.UserAction import org.schabi.newpipe.error.UserAction
import org.schabi.newpipe.extractor.ServiceList
import org.schabi.newpipe.extractor.channel.ChannelInfoItem import org.schabi.newpipe.extractor.channel.ChannelInfoItem
import org.schabi.newpipe.fragments.BaseStateFragment import org.schabi.newpipe.fragments.BaseStateFragment
import org.schabi.newpipe.ktx.animate import org.schabi.newpipe.ktx.animate
@ -45,13 +46,10 @@ import org.schabi.newpipe.local.subscription.item.EmptyPlaceholderItem
import org.schabi.newpipe.local.subscription.item.FeedGroupAddItem import org.schabi.newpipe.local.subscription.item.FeedGroupAddItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCarouselItem 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
import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem.Companion.PAYLOAD_UPDATE_VISIBILITY_MENU_ITEM 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
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 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_MODE
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE 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.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
@ -59,6 +57,7 @@ import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
import org.schabi.newpipe.streams.io.StoredFileHelper import org.schabi.newpipe.streams.io.StoredFileHelper
import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.NavigationHelper
import org.schabi.newpipe.util.OnClickGesture 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.getGridSpanCountChannels
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
import org.schabi.newpipe.util.external_communication.ShareUtils import org.schabi.newpipe.util.external_communication.ShareUtils
@ -74,12 +73,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private lateinit var subscriptionManager: SubscriptionManager private lateinit var subscriptionManager: SubscriptionManager
private val disposables: CompositeDisposable = CompositeDisposable() private val disposables: CompositeDisposable = CompositeDisposable()
private var subscriptionBroadcastReceiver: BroadcastReceiver? = null
private val groupAdapter = GroupAdapter<GroupieViewHolder<FeedItemCarouselBinding>>() private val groupAdapter = GroupAdapter<GroupieViewHolder<FeedItemCarouselBinding>>()
private val feedGroupsSection = Section() private val feedGroupsSection = Section()
private var feedGroupsCarousel: FeedGroupCarouselItem? = null private var feedGroupsCarousel: FeedGroupCarouselItem? = null
private lateinit var importExportItem: FeedImportExportItem
private lateinit var feedGroupsSortMenuItem: HeaderWithMenuItem private lateinit var feedGroupsSortMenuItem: HeaderWithMenuItem
private val subscriptionsSection = Section() private val subscriptionsSection = Section()
@ -91,12 +87,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
@State @State
@JvmField @JvmField
var itemsListState: Parcelable? = null var itemsListState: Parcelable? = null
@State @State
@JvmField @JvmField
var feedGroupsListState: Parcelable? = null var feedGroupsListState: Parcelable? = null
@State
@JvmField
var importExportItemExpandedState: Boolean? = null
init { init {
setHasOptionsMenu(true) setHasOptionsMenu(true)
@ -120,20 +114,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
return inflater.inflate(R.layout.fragment_subscription, container, false) return inflater.inflate(R.layout.fragment_subscription, container, false)
} }
override fun onResume() {
super.onResume()
setupBroadcastReceiver()
}
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
itemsListState = binding.itemsList.layoutManager?.onSaveInstanceState() itemsListState = binding.itemsList.layoutManager?.onSaveInstanceState()
feedGroupsListState = feedGroupsCarousel?.onSaveInstanceState() feedGroupsListState = feedGroupsCarousel?.onSaveInstanceState()
importExportItemExpandedState = importExportItem.isExpanded
if (subscriptionBroadcastReceiver != null && activity != null) {
LocalBroadcastManager.getInstance(activity).unregisterReceiver(subscriptionBroadcastReceiver!!)
}
} }
override fun onDestroy() { override fun onDestroy() {
@ -150,28 +134,61 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
activity.supportActionBar?.setDisplayShowTitleEnabled(true) activity.supportActionBar?.setDisplayShowTitleEnabled(true)
activity.supportActionBar?.setTitle(R.string.tab_subscriptions) activity.supportActionBar?.setTitle(R.string.tab_subscriptions)
buildImportExportMenu(menu)
} }
private fun setupBroadcastReceiver() { private fun buildImportExportMenu(menu: Menu) {
if (activity == null) return // -- Import --
val importSubMenu = menu.addSubMenu(R.string.import_from)
if (subscriptionBroadcastReceiver != null) { addMenuItemToSubmenu(importSubMenu, R.string.previous_export) { onImportPreviousSelected() }
LocalBroadcastManager.getInstance(activity).unregisterReceiver(subscriptionBroadcastReceiver!!) .setIcon(R.drawable.ic_backup)
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))
} }
val filters = IntentFilter() // -- Export --
filters.addAction(EXPORT_COMPLETE_ACTION) val exportSubMenu = menu.addSubMenu(R.string.export_to)
filters.addAction(IMPORT_COMPLETE_ACTION)
subscriptionBroadcastReceiver = object : BroadcastReceiver() { addMenuItemToSubmenu(exportSubMenu, R.string.file) { onExportSelected() }
override fun onReceive(context: Context, intent: Intent) { .setIcon(R.drawable.ic_save)
_binding?.itemsList?.post {
importExportItem.isExpanded = false
importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS)
}
}
} }
LocalBroadcastManager.getInstance(activity).registerReceiver(subscriptionBroadcastReceiver!!, filters) 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) { private fun onImportFromServiceSelected(serviceId: Int) {
@ -263,13 +280,14 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
subscriptionsSection.setPlaceholder(EmptyPlaceholderItem()) subscriptionsSection.setPlaceholder(EmptyPlaceholderItem())
subscriptionsSection.setHideWhenEmpty(true) subscriptionsSection.setHideWhenEmpty(true)
importExportItem = FeedImportExportItem( groupAdapter.add(
{ onImportPreviousSelected() }, Section(
{ onImportFromServiceSelected(it) }, HeaderWithMenuItem(
{ onExportSelected() }, getString(R.string.tab_subscriptions)
importExportItemExpandedState ?: false ),
listOf(subscriptionsSection)
)
) )
groupAdapter.add(Section(importExportItem, listOf(subscriptionsSection)))
} }
override fun initViews(rootView: View, savedInstanceState: Bundle?) { override fun initViews(rootView: View, savedInstanceState: Bundle?) {
@ -371,13 +389,6 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
subscriptionsSection.update(result.subscriptions) subscriptionsSection.update(result.subscriptions)
subscriptionsSection.setHideWhenEmpty(false) subscriptionsSection.setHideWhenEmpty(false)
if (result.subscriptions.isEmpty() && importExportItemExpandedState == null) {
binding.itemsList.post {
importExportItem.isExpanded = true
importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS)
}
}
if (itemsListState != null) { if (itemsListState != null) {
binding.itemsList.layoutManager?.onRestoreInstanceState(itemsListState) binding.itemsList.layoutManager?.onRestoreInstanceState(itemsListState)
itemsListState = null itemsListState = null

View File

@ -1,122 +0,0 @@
package org.schabi.newpipe.local.subscription.item
import android.graphics.Color
import android.graphics.PorterDuff
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import com.xwray.groupie.viewbinding.BindableItem
import com.xwray.groupie.viewbinding.GroupieViewHolder
import org.schabi.newpipe.R
import org.schabi.newpipe.databinding.FeedImportExportGroupBinding
import org.schabi.newpipe.extractor.NewPipe
import org.schabi.newpipe.extractor.exceptions.ExtractionException
import org.schabi.newpipe.ktx.animateRotation
import org.schabi.newpipe.util.ServiceHelper
import org.schabi.newpipe.util.ThemeHelper
import org.schabi.newpipe.views.CollapsibleView
class FeedImportExportItem(
val onImportPreviousSelected: () -> Unit,
val onImportFromServiceSelected: (Int) -> Unit,
val onExportSelected: () -> Unit,
var isExpanded: Boolean = false
) : BindableItem<FeedImportExportGroupBinding>() {
companion object {
const val REFRESH_EXPANDED_STATUS = 123
}
override fun bind(viewBinding: FeedImportExportGroupBinding, position: Int, payloads: MutableList<Any>) {
if (payloads.contains(REFRESH_EXPANDED_STATUS)) {
viewBinding.importExportOptions.apply { if (isExpanded) expand() else collapse() }
return
}
super.bind(viewBinding, position, payloads)
}
override fun getLayout(): Int = R.layout.feed_import_export_group
override fun bind(viewBinding: FeedImportExportGroupBinding, position: Int) {
if (viewBinding.importFromOptions.childCount == 0) setupImportFromItems(viewBinding.importFromOptions)
if (viewBinding.exportToOptions.childCount == 0) setupExportToItems(viewBinding.exportToOptions)
expandIconListener?.let { viewBinding.importExportOptions.removeListener(it) }
expandIconListener = CollapsibleView.StateListener { newState ->
viewBinding.importExportExpandIcon.animateRotation(
250, if (newState == CollapsibleView.COLLAPSED) 0 else 180
)
}
viewBinding.importExportOptions.currentState = if (isExpanded) CollapsibleView.EXPANDED else CollapsibleView.COLLAPSED
viewBinding.importExportExpandIcon.rotation = if (isExpanded) 180F else 0F
viewBinding.importExportOptions.ready()
viewBinding.importExportOptions.addListener(expandIconListener)
viewBinding.importExport.setOnClickListener {
viewBinding.importExportOptions.switchState()
isExpanded = viewBinding.importExportOptions.currentState == CollapsibleView.EXPANDED
}
}
override fun unbind(viewHolder: GroupieViewHolder<FeedImportExportGroupBinding>) {
super.unbind(viewHolder)
expandIconListener?.let { viewHolder.binding.importExportOptions.removeListener(it) }
expandIconListener = null
}
override fun initializeViewBinding(view: View) = FeedImportExportGroupBinding.bind(view)
private var expandIconListener: CollapsibleView.StateListener? = null
private fun addItemView(title: String, @DrawableRes icon: Int, container: ViewGroup): View {
val itemRoot = View.inflate(container.context, R.layout.subscription_import_export_item, null)
val titleView = itemRoot.findViewById<TextView>(android.R.id.text1)
val iconView = itemRoot.findViewById<ImageView>(android.R.id.icon1)
titleView.text = title
iconView.setImageResource(icon)
container.addView(itemRoot)
return itemRoot
}
private fun setupImportFromItems(listHolder: ViewGroup) {
val previousBackupItem = addItemView(
listHolder.context.getString(R.string.previous_export),
R.drawable.ic_backup, listHolder
)
previousBackupItem.setOnClickListener { onImportPreviousSelected() }
val iconColor = if (ThemeHelper.isLightThemeSelected(listHolder.context)) Color.BLACK else Color.WHITE
val services = listHolder.context.resources.getStringArray(R.array.service_list)
for (serviceName in services) {
try {
val service = NewPipe.getService(serviceName)
val subscriptionExtractor = service.subscriptionExtractor ?: continue
val supportedSources = subscriptionExtractor.supportedSources
if (supportedSources.isEmpty()) continue
val itemView = addItemView(serviceName, ServiceHelper.getIcon(service.serviceId), listHolder)
val iconView = itemView.findViewById<ImageView>(android.R.id.icon1)
iconView.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
itemView.setOnClickListener { onImportFromServiceSelected(service.serviceId) }
} catch (e: ExtractionException) {
throw RuntimeException("Services array contains an entry that it's not a valid service name ($serviceName)", e)
}
}
}
private fun setupExportToItems(listHolder: ViewGroup) {
val previousBackupItem = addItemView(
listHolder.context.getString(R.string.file),
R.drawable.ic_save, listHolder
)
previousBackupItem.setOnClickListener { onExportSelected() }
}
}

View File

@ -207,7 +207,7 @@ public class PeertubeInstanceListFragment extends Fragment {
new AlertDialog.Builder(c) new AlertDialog.Builder(c)
.setTitle(R.string.peertube_instance_add_title) .setTitle(R.string.peertube_instance_add_title)
.setIcon(R.drawable.place_holder_peertube) .setIcon(R.drawable.ic_placeholder_peertube)
.setView(dialogBinding.getRoot()) .setView(dialogBinding.getRoot())
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok, (dialog1, which) -> { .setPositiveButton(R.string.ok, (dialog1, which) -> {
@ -411,7 +411,7 @@ public class PeertubeInstanceListFragment extends Fragment {
lastChecked = instanceRB; lastChecked = instanceRB;
} }
}); });
instanceIconView.setImageResource(R.drawable.place_holder_peertube); instanceIconView.setImageResource(R.drawable.ic_placeholder_peertube);
} }
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")

View File

@ -31,17 +31,17 @@ public final class ServiceHelper {
public static int getIcon(final int serviceId) { public static int getIcon(final int serviceId) {
switch (serviceId) { switch (serviceId) {
case 0: case 0:
return R.drawable.place_holder_youtube; return R.drawable.ic_smart_display;
case 1: case 1:
return R.drawable.place_holder_cloud; return R.drawable.ic_cloud;
case 2: case 2:
return R.drawable.place_holder_gadse; return R.drawable.ic_placeholder_media_ccc;
case 3: case 3:
return R.drawable.place_holder_peertube; return R.drawable.ic_placeholder_peertube;
case 4: case 4:
return R.drawable.place_holder_bandcamp; return R.drawable.ic_placeholder_bandcamp;
default: default:
return R.drawable.place_holder_circle; return R.drawable.ic_circle;
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:tint="@color/defaultIconTint" >
<path
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.49 10,-10S17.52,2 12,2L12,2z"
android:fillColor="#FF000000" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="@color/defaultIconTint">
<path
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96z"
android:fillColor="#FF000000" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportHeight="97.75"
android:viewportWidth="97.75"
android:tint="@color/defaultIconTint">
<path
android:pathData="M48.875,0C21.882,0 0,21.882 0,48.875S21.882,97.75 48.875,97.75 97.75,75.868 97.75,48.875 75.868,0 48.875,0zM64.835,70.857L12.593,70.857l20.32,-43.965h52.244L64.835,70.857z"
android:fillColor="#FF000000" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="26.458319"
android:viewportHeight="26.458332"
android:tint="@color/defaultIconTint">
<path
android:pathData="M13.23,0.302C6.07,0.302 0.264,6.107 0.264,13.267a12.965,12.965 0,0 0,0.847 4.595c0.19,-0.497 0.408,-0.982 0.682,-1.438 0.14,-0.232 0.294,-0.457 0.396,-0.707 0.103,-0.25 0.15,-0.533 0.072,-0.792a1.362,1.362 0,0 0,-0.22 -0.404c-0.092,-0.123 -0.192,-0.24 -0.275,-0.37a1.662,1.662 0,0 1,-0.255 -1.12,1.5 1.5,0 0,1 0.58,-0.987c0.28,-0.208 0.635,-0.3 0.985,-0.288a1.757,1.757 0,0 1,0.346 0.048c0.452,0.11 0.852,0.393 1.148,0.75 0.368,0.447 0.584,1.01 0.637,1.586a3.574,3.574 0,0 1,-0.275 1.693c-0.4,0.955 -1.15,1.725 -1.565,2.673 -0.338,0.775 -0.435,1.638 -0.39,2.483 0.007,0.077 0.018,0.155 0.025,0.234a12.965,12.965 0,0 0,3.62 3.18,17.63 17.63,0 0,1 -0.13,-2.11c0.002,-0.56 0.03,-1.12 0.085,-1.675 -0.34,-0.236 -0.65,-0.51 -0.87,-0.86 -0.392,-0.62 -0.466,-1.408 -0.305,-2.124 0.16,-0.717 0.54,-1.37 0.997,-1.945a7.833,7.833 0,0 1,2.835 -2.223,10.305 10.305,0 0,1 -0.09,-0.126 4.854,4.854 0,0 1,-0.702 -2.176c-0.06,-0.777 0.064,-1.554 0.115,-2.33 0.037,-0.543 0.04,-1.085 0.07,-1.627 0.038,-0.627 0.114,-1.255 0.29,-1.858a2.36,2.36 0,0 1,0.266 -0.63,1.4 1.4,0 0,1 0.594,-0.514c0.274,-0.108 0.51,-0.132 0.776,-0.087 0.22,0.046 0.425,0.156 0.604,0.294 0.18,0.138 0.335,0.304 0.48,0.477a7.298,7.298 0,0 1,1.04 1.617,3.57 3.57,0 0,1 1.09,0 7.287,7.287 0,0 1,1.04 -1.616,3.21 3.21,0 0,1 0.48,-0.476c0.18,-0.14 0.383,-0.248 0.604,-0.295a1.268,1.268 0,0 1,0.78 0.086,1.402 1.402,0 0,1 0.595,0.517c0.124,0.19 0.202,0.408 0.266,0.626 0.175,0.602 0.252,1.23 0.29,1.856 0.03,0.543 0.033,1.087 0.07,1.628 0.05,0.777 0.175,1.554 0.116,2.33a4.855,4.855 0,0 1,-0.705 2.178c-0.03,0.05 -0.07,0.096 -0.103,0.145 0.247,0.278 0.598,0.513 0.898,0.614a1.956,1.956 0,0 0,1.05 0.044,1.65 1.65,0 0,0 0.533,-0.226 1.253,1.253 0,0 0,0.397 -0.418c0.118,-0.21 0.166,-0.45 0.192,-0.687 0.067,-0.61 0,-1.224 -0.05,-1.835 -0.034,-0.396 -0.062,-0.8 0.027,-1.187 0.06,-0.26 0.177,-0.518 0.373,-0.7a1.106,1.106 0,0 1,0.465 -0.255,1.312 1.312,0 0,1 0.53,-0.03c0.38,0.057 0.736,0.274 0.948,0.594 0.12,0.18 0.194,0.39 0.238,0.604 0.044,0.213 0.06,0.43 0.072,0.648 0.04,0.76 0.04,1.522 0.018,2.284 -0.018,0.665 -0.055,1.348 -0.32,1.957 -0.343,0.782 -1.032,1.366 -1.775,1.786a7.052,7.052 0,0 1,-1.588 0.647c0.482,1.54 0.733,3.24 0.733,4.968a17.6,17.6 0,0 1,-0.135 2.125,12.964 12.964,0 0,0 6.384,-11.152c0,-7.16 -5.806,-12.965 -12.965,-12.965zM9.602,16.284v1.483a1.88,1.88 0,0 1,1.083 0.362,1.738 1.738,0 0,1 0.556,0.68c0.122,0.27 0.166,0.576 0.116,0.868a1.493,1.493 0,0 1,-0.332 0.708,1.647 1.647,0 0,1 -0.635,0.458 1.738,1.738 0,0 1,-0.787 0.122v3.73l7.762,-4.208 -7.762,-4.204z"
android:fillColor="#FF000000" />
</vector>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:tint="@color/defaultIconTint">
<path
android:pathData="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM9.5 16.5v-9l7 4.5-7 4.5z"
android:fillColor="#FF000000"/>
</vector>

View File

@ -86,7 +86,7 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
app:tint="@color/drawer_header_font_color" app:tint="@color/drawer_header_font_color"
tools:ignore="ContentDescription" tools:ignore="ContentDescription"
tools:srcCompat="@drawable/place_holder_youtube" /> tools:srcCompat="@drawable/ic_smart_display" />
<org.schabi.newpipe.views.NewPipeTextView <org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/drawer_header_service_view" android:id="@+id/drawer_header_service_view"

View File

@ -1,114 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="14dp"
android:background="?attr/contrast_background_color">
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="?attr/toolbar_shadow" />
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/separator_color" />
<LinearLayout
android:id="@+id/import_export"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<org.schabi.newpipe.views.NewPipeTextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="16dp"
android:paddingTop="8dp"
android:paddingRight="16dp"
android:paddingBottom="8dp"
android:text="@string/tab_subscriptions"
android:textColor="?android:attr/textColorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/import_export_expand_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginRight="16dp"
app:srcCompat="@drawable/ic_expand_more"
tools:ignore="ContentDescription,RtlHardcoded" />
</LinearLayout>
<org.schabi.newpipe.views.CollapsibleView
android:id="@+id/import_export_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="6dp"
tools:ignore="RtlSymmetry">
<org.schabi.newpipe.views.NewPipeTextView
android:layout_width="match_parent"
android:layout_height="@dimen/subscription_import_export_title_height"
android:gravity="left|center"
android:maxLines="1"
android:paddingLeft="36dp"
android:text="@string/import_from"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="13sp"
tools:ignore="RtlHardcoded" />
<LinearLayout
android:id="@+id/import_from_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:layout_marginLeft="36dp"
android:orientation="vertical" />
<org.schabi.newpipe.views.NewPipeTextView
android:layout_width="match_parent"
android:layout_height="@dimen/subscription_import_export_title_height"
android:background="?attr/selectableItemBackground"
android:gravity="left|center"
android:maxLines="1"
android:paddingLeft="36dp"
android:text="@string/export_to"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="13sp"
tools:ignore="RtlHardcoded" />
<LinearLayout
android:id="@+id/export_to_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:orientation="vertical" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="8dp"
android:background="?attr/separator_color" />
</org.schabi.newpipe.views.CollapsibleView>
</LinearLayout>

View File

@ -26,7 +26,7 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
tools:ignore="ContentDescription,RtlHardcoded" tools:ignore="ContentDescription,RtlHardcoded"
tools:src="@drawable/place_holder_peertube" /> tools:src="@drawable/ic_placeholder_peertube" />
<TextView <TextView
android:id="@+id/instanceName" android:id="@+id/instanceName"

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal">
<ImageView
android:id="@android:id/icon1"
android:layout_width="48dp"
android:layout_height="@dimen/subscription_import_export_item_icon_size"
android:layout_marginTop="@dimen/subscription_import_export_item_icon_margin"
android:layout_marginBottom="@dimen/subscription_import_export_item_icon_margin"
android:scaleType="fitCenter"
tools:ignore="ContentDescription,RtlHardcoded"
tools:src="@drawable/place_holder_youtube" />
<org.schabi.newpipe.views.NewPipeTextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="@dimen/subscription_import_export_item_height"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="13sp"
tools:text="@string/youtube" />
</LinearLayout>

View File

@ -58,11 +58,6 @@
<dimen name="popup_minimum_width">150dp</dimen> <dimen name="popup_minimum_width">150dp</dimen>
<dimen name="comment_item_avatar_right_margin">9dp</dimen> <dimen name="comment_item_avatar_right_margin">9dp</dimen>
<dimen name="subscription_import_export_title_height">32dp</dimen>
<dimen name="subscription_import_export_item_height">42dp</dimen>
<dimen name="subscription_import_export_item_icon_size">24dp</dimen>
<!-- (item_height - item_icon_size) / 2-->
<dimen name="subscription_import_export_item_icon_margin">9dp</dimen>
<!-- Video Item Detail View Dimensions--> <!-- Video Item Detail View Dimensions-->
<!-- Text Size --> <!-- Text Size -->
<dimen name="video_item_detail_title_text_size">15sp</dimen> <dimen name="video_item_detail_title_text_size">15sp</dimen>

View File

@ -4,10 +4,6 @@
<string name="last_used_preferences_version">last_used_preferences_version</string> <string name="last_used_preferences_version">last_used_preferences_version</string>
<!-- Service --> <!-- Service -->
<string-array name="service_list">
<item>@string/youtube</item>
<item>@string/soundcloud</item>
</string-array>
<string name="current_service_key">service</string> <string name="current_service_key">service</string>
<string name="default_service_value">@string/youtube</string> <string name="default_service_value">@string/youtube</string>

View File

@ -69,14 +69,17 @@
<style name="DarkPopupMenu" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> <style name="DarkPopupMenu" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar"> <style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="popupTheme">@style/ThemeOverlay.AppCompat.DayNight.ActionBar</item> <item name="popupTheme">@style/ToolbarPopupTheme</item>
<item name="android:textColorPrimary">?attr/actionColor</item> <item name="android:textColorPrimary">?attr/actionColor</item>
<item name="android:textColorSecondary">?attr/actionColor</item> <item name="android:textColorSecondary">?attr/actionColor</item>
<item name="tint">?attr/actionColor</item> <item name="tint">?attr/actionColor</item>
<item name="iconTint">?attr/actionColor</item> <item name="iconTint">?attr/actionColor</item>
</style> </style>
<style name="ToolbarPopupTheme" parent="ThemeOverlay.AppCompat.DayNight.ActionBar">
<item name="tint">@color/contrastColor</item>
</style>
<style name="ContrastToolbarTheme" parent="ThemeOverlay.AppCompat.DayNight.ActionBar"> <style name="ContrastToolbarTheme" parent="ThemeOverlay.AppCompat.DayNight.ActionBar">
<item name="popupTheme">@style/ThemeOverlay.AppCompat.DayNight.ActionBar</item> <item name="popupTheme">@style/ToolbarPopupTheme</item>
<item name="android:textColorPrimary">@color/contrastColor</item> <item name="android:textColorPrimary">@color/contrastColor</item>
<item name="android:textColorSecondary">@color/contrastColor</item> <item name="android:textColorSecondary">@color/contrastColor</item>
<item name="tint">@color/contrastColor</item> <item name="tint">@color/contrastColor</item>