Merge branch 'dev' into OnClickGesture_interface

This commit is contained in:
Isira Seneviratne 2022-08-04 06:10:39 +05:30
commit 7f018b90db
10 changed files with 48 additions and 59 deletions

View File

@ -97,12 +97,12 @@ android {
ext { ext {
checkstyleVersion = '10.3.1' checkstyleVersion = '10.3.1'
androidxLifecycleVersion = '2.3.1' androidxLifecycleVersion = '2.5.1'
androidxRoomVersion = '2.4.2' androidxRoomVersion = '2.4.2'
androidxWorkVersion = '2.7.1' androidxWorkVersion = '2.7.1'
icepickVersion = '3.2.0' icepickVersion = '3.2.0'
exoPlayerVersion = '2.18.0' exoPlayerVersion = '2.18.1'
googleAutoServiceVersion = '1.0.1' googleAutoServiceVersion = '1.0.1'
groupieVersion = '2.10.1' groupieVersion = '2.10.1'
markwonVersion = '4.6.2' markwonVersion = '4.6.2'
@ -197,14 +197,14 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}"
/** AndroidX **/ /** AndroidX **/
implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.core:core-ktx:1.8.0' implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.documentfile:documentfile:1.0.1' implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.fragment:fragment-ktx:1.3.6' implementation 'androidx.fragment:fragment-ktx:1.4.1'
implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0' implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
implementation 'androidx.media:media:1.6.0' implementation 'androidx.media:media:1.6.0'
implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.preference:preference:1.2.0'
@ -218,7 +218,7 @@ dependencies {
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01' implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation "androidx.work:work-runtime-ktx:${androidxWorkVersion}" implementation "androidx.work:work-runtime-ktx:${androidxWorkVersion}"
implementation "androidx.work:work-rxjava3:${androidxWorkVersion}" implementation "androidx.work:work-rxjava3:${androidxWorkVersion}"
implementation 'com.google.android.material:material:1.5.0' implementation 'com.google.android.material:material:1.6.1'
/** Third-party libraries **/ /** Third-party libraries **/
// Instance state boilerplate elimination // Instance state boilerplate elimination

View File

@ -14,8 +14,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor.DeobfuscateException import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor.DeobfuscateException
import org.schabi.newpipe.ktx.isNetworkRelated import org.schabi.newpipe.ktx.isNetworkRelated
import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ServiceHelper
import java.io.PrintWriter
import java.io.StringWriter
@Parcelize @Parcelize
class ErrorInfo( class ErrorInfo(
@ -80,19 +78,10 @@ class ErrorInfo(
companion object { companion object {
const val SERVICE_NONE = "none" const val SERVICE_NONE = "none"
private fun getStackTrace(throwable: Throwable): String { fun throwableToStringList(throwable: Throwable) = arrayOf(throwable.stackTraceToString())
StringWriter().use { stringWriter ->
PrintWriter(stringWriter, true).use { printWriter ->
throwable.printStackTrace(printWriter)
return stringWriter.buffer.toString()
}
}
}
fun throwableToStringList(throwable: Throwable) = arrayOf(getStackTrace(throwable)) fun throwableListToStringList(throwableList: List<Throwable>) =
throwableList.map { it.stackTraceToString() }.toTypedArray()
fun throwableListToStringList(throwable: List<Throwable>) =
Array(throwable.size) { i -> getStackTrace(throwable[i]) }
private fun getInfoServiceName(info: Info?) = private fun getInfoServiceName(info: Info?) =
if (info == null) SERVICE_NONE else ServiceHelper.getNameOfServiceById(info.serviceId) if (info == null) SERVICE_NONE else ServiceHelper.getNameOfServiceById(info.serviceId)

View File

@ -202,10 +202,9 @@ public class DescriptionFragment extends BaseFragment {
private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) {
if (streamInfo.getTags() != null && !streamInfo.getTags().isEmpty()) { if (streamInfo.getTags() != null && !streamInfo.getTags().isEmpty()) {
final ItemMetadataTagsBinding itemBinding = final var itemBinding = ItemMetadataTagsBinding.inflate(inflater, layout, false);
ItemMetadataTagsBinding.inflate(inflater, layout, false);
streamInfo.getTags().stream().sorted().forEach(tag -> { streamInfo.getTags().stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(tag -> {
final Chip chip = (Chip) inflater.inflate(R.layout.chip, final Chip chip = (Chip) inflater.inflate(R.layout.chip,
itemBinding.metadataTagsChips, false); itemBinding.metadataTagsChips, false);
chip.setText(tag); chip.setText(tag);

View File

@ -1312,9 +1312,11 @@ public final class VideoDetailFragment
// Prevent from re-adding a view multiple times // Prevent from re-adding a view multiple times
new Handler(Looper.getMainLooper()).post(() -> new Handler(Looper.getMainLooper()).post(() ->
player.UIs().get(MainPlayerUi.class).ifPresent(playerUi -> { player.UIs().get(MainPlayerUi.class).ifPresent(playerUi -> {
playerUi.removeViewFromParent(); if (binding != null) {
binding.playerPlaceholder.addView(playerUi.getBinding().getRoot()); playerUi.removeViewFromParent();
playerUi.setupVideoSurfaceIfNeeded(); binding.playerPlaceholder.addView(playerUi.getBinding().getRoot());
playerUi.setupVideoSurfaceIfNeeded();
}
})); }));
} }

View File

@ -135,8 +135,8 @@ class FeedFragment : BaseStateFragment<FeedState>() {
_feedBinding = FragmentFeedBinding.bind(rootView) _feedBinding = FragmentFeedBinding.bind(rootView)
super.onViewCreated(rootView, savedInstanceState) super.onViewCreated(rootView, savedInstanceState)
val factory = FeedViewModel.Factory(requireContext(), groupId) val factory = FeedViewModel.getFactory(requireContext(), groupId)
viewModel = ViewModelProvider(this, factory).get(FeedViewModel::class.java) viewModel = ViewModelProvider(this, factory)[FeedViewModel::class.java]
showPlayedItems = viewModel.getShowPlayedItemsFromPreferences() showPlayedItems = viewModel.getShowPlayedItemsFromPreferences()
showFutureItems = viewModel.getShowFutureItemsFromPreferences() showFutureItems = viewModel.getShowFutureItemsFromPreferences()
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) } viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) }

View File

@ -1,17 +1,20 @@
package org.schabi.newpipe.local.feed package org.schabi.newpipe.local.feed
import android.app.Application
import android.content.Context import android.content.Context
import androidx.core.content.edit import androidx.core.content.edit
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.functions.Function5 import io.reactivex.rxjava3.functions.Function5
import io.reactivex.rxjava3.processors.BehaviorProcessor import io.reactivex.rxjava3.processors.BehaviorProcessor
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.App
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.database.stream.StreamWithState import org.schabi.newpipe.database.stream.StreamWithState
@ -26,12 +29,12 @@ import java.time.OffsetDateTime
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class FeedViewModel( class FeedViewModel(
private val applicationContext: Context, private val application: Application,
groupId: Long = FeedGroupEntity.GROUP_ALL_ID, groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
initialShowPlayedItems: Boolean = true, initialShowPlayedItems: Boolean = true,
initialShowFutureItems: Boolean = true initialShowFutureItems: Boolean = true
) : ViewModel() { ) : ViewModel() {
private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(applicationContext) private val feedDatabaseManager = FeedDatabaseManager(application)
private val toggleShowPlayedItems = BehaviorProcessor.create<Boolean>() private val toggleShowPlayedItems = BehaviorProcessor.create<Boolean>()
private val toggleShowPlayedItemsFlowable = toggleShowPlayedItems private val toggleShowPlayedItemsFlowable = toggleShowPlayedItems
@ -113,24 +116,24 @@ class FeedViewModel(
} }
fun saveShowPlayedItemsToPreferences(showPlayedItems: Boolean) = fun saveShowPlayedItemsToPreferences(showPlayedItems: Boolean) =
PreferenceManager.getDefaultSharedPreferences(applicationContext).edit { PreferenceManager.getDefaultSharedPreferences(application).edit {
this.putBoolean(applicationContext.getString(R.string.feed_show_played_items_key), showPlayedItems) this.putBoolean(application.getString(R.string.feed_show_played_items_key), showPlayedItems)
this.apply() this.apply()
} }
fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(applicationContext) fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(application)
fun toggleFutureItems(showFutureItems: Boolean) { fun toggleFutureItems(showFutureItems: Boolean) {
toggleShowFutureItems.onNext(showFutureItems) toggleShowFutureItems.onNext(showFutureItems)
} }
fun saveShowFutureItemsToPreferences(showFutureItems: Boolean) = fun saveShowFutureItemsToPreferences(showFutureItems: Boolean) =
PreferenceManager.getDefaultSharedPreferences(applicationContext).edit { PreferenceManager.getDefaultSharedPreferences(application).edit {
this.putBoolean(applicationContext.getString(R.string.feed_show_future_items_key), showFutureItems) this.putBoolean(application.getString(R.string.feed_show_future_items_key), showFutureItems)
this.apply() this.apply()
} }
fun getShowFutureItemsFromPreferences() = getShowFutureItemsFromPreferences(applicationContext) fun getShowFutureItemsFromPreferences() = getShowFutureItemsFromPreferences(application)
companion object { companion object {
private fun getShowPlayedItemsFromPreferences(context: Context) = private fun getShowPlayedItemsFromPreferences(context: Context) =
@ -139,21 +142,16 @@ class FeedViewModel(
private fun getShowFutureItemsFromPreferences(context: Context) = private fun getShowFutureItemsFromPreferences(context: Context) =
PreferenceManager.getDefaultSharedPreferences(context) PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.feed_show_future_items_key), true) .getBoolean(context.getString(R.string.feed_show_future_items_key), true)
} fun getFactory(context: Context, groupId: Long) = viewModelFactory {
initializer {
class Factory( FeedViewModel(
private val context: Context, App.getApp(),
private val groupId: Long = FeedGroupEntity.GROUP_ALL_ID groupId,
) : ViewModelProvider.Factory { // Read initial value from preferences
@Suppress("UNCHECKED_CAST") getShowPlayedItemsFromPreferences(context.applicationContext),
override fun <T : ViewModel?> create(modelClass: Class<T>): T { getShowFutureItemsFromPreferences(context.applicationContext)
return FeedViewModel( )
context.applicationContext, }
groupId,
// Read initial value from preferences
getShowPlayedItemsFromPreferences(context.applicationContext),
getShowFutureItemsFromPreferences(context.applicationContext)
) as T
} }
} }
} }

View File

@ -122,7 +122,7 @@ class FeedGroupDialogViewModel(
private val initialShowOnlyUngrouped: Boolean = false private val initialShowOnlyUngrouped: Boolean = false
) : ViewModelProvider.Factory { ) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T { override fun <T : ViewModel> create(modelClass: Class<T>): T {
return FeedGroupDialogViewModel( return FeedGroupDialogViewModel(
context.applicationContext, context.applicationContext,
groupId, initialQuery, initialShowOnlyUngrouped groupId, initialQuery, initialShowOnlyUngrouped

View File

@ -1,5 +1,5 @@
/* /*
* Based on ExoPlayer's DefaultHttpDataSource, version 2.18.0. * Based on ExoPlayer's DefaultHttpDataSource, version 2.18.1.
* *
* Original source code copyright (C) 2016 The Android Open Source Project, licensed under the * Original source code copyright (C) 2016 The Android Open Source Project, licensed under the
* Apache License, Version 2.0. * Apache License, Version 2.0.

View File

@ -8,6 +8,7 @@ import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetBehavior;
@ -18,7 +19,8 @@ import java.util.List;
public class CustomBottomSheetBehavior extends BottomSheetBehavior<FrameLayout> { public class CustomBottomSheetBehavior extends BottomSheetBehavior<FrameLayout> {
public CustomBottomSheetBehavior(final Context context, final AttributeSet attrs) { public CustomBottomSheetBehavior(@NonNull final Context context,
@Nullable final AttributeSet attrs) {
super(context, attrs); super(context, attrs);
} }
@ -32,7 +34,7 @@ public class CustomBottomSheetBehavior extends BottomSheetBehavior<FrameLayout>
@Override @Override
public boolean onInterceptTouchEvent(@NonNull final CoordinatorLayout parent, public boolean onInterceptTouchEvent(@NonNull final CoordinatorLayout parent,
@NonNull final FrameLayout child, @NonNull final FrameLayout child,
final MotionEvent event) { @NonNull final MotionEvent event) {
// Drop following when action ends // Drop following when action ends
if (event.getAction() == MotionEvent.ACTION_CANCEL if (event.getAction() == MotionEvent.ACTION_CANCEL
|| event.getAction() == MotionEvent.ACTION_UP) { || event.getAction() == MotionEvent.ACTION_UP) {

View File

@ -11,7 +11,6 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.LayerDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.SeekBar; import android.widget.SeekBar;
@ -149,7 +148,7 @@ public class PlaybackParameterDialog extends DialogFragment {
assureCorrectAppLanguage(getContext()); assureCorrectAppLanguage(getContext());
Icepick.restoreInstanceState(this, savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState);
binding = DialogPlaybackParameterBinding.inflate(LayoutInflater.from(getContext())); binding = DialogPlaybackParameterBinding.inflate(getLayoutInflater());
initUI(); initUI();
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireActivity()) final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireActivity())