Merge branch 'TeamNewPipe:dev' into fixing-ui-crash-11468

This commit is contained in:
Elva Kang 2024-10-24 11:11:37 +11:00 committed by GitHub
commit 63bc982cb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 278 additions and 117 deletions

View file

@ -47,10 +47,10 @@ jobs:
BRANCH: ${{ github.head_ref }} BRANCH: ${{ github.head_ref }}
run: git checkout -B "$BRANCH" run: git checkout -B "$BRANCH"
- name: set up JDK 17 - name: set up JDK
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
java-version: 17 java-version: 21
distribution: "temurin" distribution: "temurin"
cache: 'gradle' cache: 'gradle'
@ -88,10 +88,10 @@ jobs:
sudo udevadm control --reload-rules sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm sudo udevadm trigger --name-match=kvm
- name: set up JDK 17 - name: set up JDK
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
java-version: 17 java-version: 21
distribution: "temurin" distribution: "temurin"
cache: 'gradle' cache: 'gradle'
@ -121,10 +121,10 @@ jobs:
with: with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17 - name: Set up JDK
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
java-version: 17 java-version: 21
distribution: "temurin" distribution: "temurin"
cache: 'gradle' cache: 'gradle'

View file

@ -92,6 +92,7 @@ android {
buildFeatures { buildFeatures {
viewBinding true viewBinding true
buildConfig true
} }
packagingOptions { packagingOptions {
@ -112,7 +113,7 @@ ext {
androidxRoomVersion = '2.6.1' androidxRoomVersion = '2.6.1'
androidxWorkVersion = '2.8.1' androidxWorkVersion = '2.8.1'
icepickVersion = '3.2.0' stateSaverVersion = '1.4.1'
exoPlayerVersion = '2.18.7' exoPlayerVersion = '2.18.7'
googleAutoServiceVersion = '1.1.1' googleAutoServiceVersion = '1.1.1'
groupieVersion = '2.10.1' groupieVersion = '2.10.1'
@ -198,7 +199,8 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test // name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/ // This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.2' // WORKAROUND: v0.24.2 can't be resolved by jitpack -> use git commit hash instead
implementation 'com.github.TeamNewPipe:NewPipeExtractor:176da72cb4c3ec4679211339b0e59f6b01bf2f52'
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
/** Checkstyle **/ /** Checkstyle **/
@ -234,8 +236,9 @@ dependencies {
/** Third-party libraries **/ /** Third-party libraries **/
// Instance state boilerplate elimination // Instance state boilerplate elimination
implementation "frankiesardo:icepick:${icepickVersion}" implementation 'com.github.livefront:bridge:v2.0.2'
kapt "frankiesardo:icepick-processor:${icepickVersion}" implementation "com.evernote:android-state:$stateSaverVersion"
kapt "com.evernote:android-state-processor:$stateSaverVersion"
// HTML parser // HTML parser
implementation "org.jsoup:jsoup:1.17.2" implementation "org.jsoup:jsoup:1.17.2"

View file

@ -13,15 +13,6 @@
## Rules for ExoPlayer ## Rules for ExoPlayer
-keep class com.google.android.exoplayer2.** { *; } -keep class com.google.android.exoplayer2.** { *; }
## Rules for Icepick. Copy pasted from https://github.com/frankiesardo/icepick
-dontwarn icepick.**
-keep class icepick.** { *; }
-keep class **$$Icepick { *; }
-keepclasseswithmembernames class * {
@icepick.* <fields>;
}
-keepnames class * { @icepick.State *;}
## Rules for OkHttp. Copy pasted from https://github.com/square/okhttp ## Rules for OkHttp. Copy pasted from https://github.com/square/okhttp
-dontwarn okhttp3.** -dontwarn okhttp3.**
-dontwarn okio.** -dontwarn okio.**

View file

@ -19,11 +19,12 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.ktx.ExceptionUtils; import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.settings.NewPipeSettings; import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.util.BridgeStateSaverInitializer;
import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.StateSaver;
import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.image.PreferredImageQuality; import org.schabi.newpipe.util.image.PreferredImageQuality;
import java.io.IOException; import java.io.IOException;
@ -101,6 +102,7 @@ public class App extends Application {
Localization.getPreferredContentCountry(this)); Localization.getPreferredContentCountry(this));
Localization.initPrettyTime(Localization.resolvePrettyTime(getApplicationContext())); Localization.initPrettyTime(Localization.resolvePrettyTime(getApplicationContext()));
BridgeStateSaverInitializer.init(this);
StateSaver.init(this); StateSaver.init(this);
initNotificationChannels(); initNotificationChannels();

View file

@ -10,8 +10,9 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import icepick.Icepick; import com.evernote.android.state.State;
import icepick.State; import com.livefront.bridge.Bridge;
public abstract class BaseFragment extends Fragment { public abstract class BaseFragment extends Fragment {
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()); protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
@ -48,7 +49,7 @@ public abstract class BaseFragment extends Fragment {
+ "savedInstanceState = [" + savedInstanceState + "]"); + "savedInstanceState = [" + savedInstanceState + "]");
} }
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Icepick.restoreInstanceState(this, savedInstanceState); Bridge.restoreInstanceState(this, savedInstanceState);
if (savedInstanceState != null) { if (savedInstanceState != null) {
onRestoreInstanceState(savedInstanceState); onRestoreInstanceState(savedInstanceState);
} }
@ -70,7 +71,7 @@ public abstract class BaseFragment extends Fragment {
@Override @Override
public void onSaveInstanceState(@NonNull final Bundle outState) { public void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState); Bridge.saveInstanceState(this, outState);
} }
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) { protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {

View file

@ -41,6 +41,9 @@ import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.evernote.android.state.State;
import com.livefront.bridge.Bridge;
import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.ListRadioIconItemBinding; import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding; import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
@ -98,8 +101,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import icepick.Icepick;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
@ -152,7 +153,7 @@ public class RouterActivity extends AppCompatActivity {
getWindow().setAttributes(params); getWindow().setAttributes(params);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Icepick.restoreInstanceState(this, savedInstanceState); Bridge.restoreInstanceState(this, savedInstanceState);
// FragmentManager will take care to recreate (Playlist|Download)Dialog when screen rotates // FragmentManager will take care to recreate (Playlist|Download)Dialog when screen rotates
// We used to .setOnDismissListener(dialog -> finish()); when creating these DialogFragments // We used to .setOnDismissListener(dialog -> finish()); when creating these DialogFragments
@ -197,7 +198,7 @@ public class RouterActivity extends AppCompatActivity {
@Override @Override
protected void onSaveInstanceState(@NonNull final Bundle outState) { protected void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState); Bridge.saveInstanceState(this, outState);
} }
@Override @Override

View file

@ -138,8 +138,12 @@ class AboutActivity : AppCompatActivity() {
"https://github.com/lisawray/groupie", StandardLicenses.MIT "https://github.com/lisawray/groupie", StandardLicenses.MIT
), ),
SoftwareComponent( SoftwareComponent(
"Icepick", "2015", "Frankie Sardo", "Android-State", "2018", "Evernote",
"https://github.com/frankiesardo/icepick", StandardLicenses.EPL1 "https://github.com/Evernote/android-state", StandardLicenses.EPL1
),
SoftwareComponent(
"Bridge", "2021", "Livefront",
"https://github.com/livefront/bridge", StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"Jsoup", "2009 - 2020", "Jonathan Hedley", "Jsoup", "2009 - 2020", "Jonathan Hedley",

View file

@ -39,6 +39,8 @@ import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.evernote.android.state.State;
import com.livefront.bridge.Bridge;
import com.nononsenseapps.filepicker.Utils; import com.nononsenseapps.filepicker.Utils;
import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.MainActivity;
@ -59,6 +61,8 @@ import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
import org.schabi.newpipe.streams.io.StoredDirectoryHelper; import org.schabi.newpipe.streams.io.StoredDirectoryHelper;
import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.streams.io.StoredFileHelper;
import org.schabi.newpipe.util.AudioTrackAdapter;
import org.schabi.newpipe.util.AudioTrackAdapter.AudioTracksWrapper;
import org.schabi.newpipe.util.FilePickerActivityHelper; import org.schabi.newpipe.util.FilePickerActivityHelper;
import org.schabi.newpipe.util.FilenameUtils; import org.schabi.newpipe.util.FilenameUtils;
import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.ListHelper;
@ -67,8 +71,6 @@ import org.schabi.newpipe.util.SecondaryStreamHelper;
import org.schabi.newpipe.util.SimpleOnSeekBarChangeListener; import org.schabi.newpipe.util.SimpleOnSeekBarChangeListener;
import org.schabi.newpipe.util.StreamItemAdapter; import org.schabi.newpipe.util.StreamItemAdapter;
import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper; import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper;
import org.schabi.newpipe.util.AudioTrackAdapter;
import org.schabi.newpipe.util.AudioTrackAdapter.AudioTracksWrapper;
import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.ThemeHelper;
import java.io.File; import java.io.File;
@ -79,8 +81,6 @@ import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import icepick.Icepick;
import icepick.State;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
import us.shandian.giga.get.MissionRecoveryInfo; import us.shandian.giga.get.MissionRecoveryInfo;
import us.shandian.giga.postprocessing.Postprocessing; import us.shandian.giga.postprocessing.Postprocessing;
@ -214,7 +214,7 @@ public class DownloadDialog extends DialogFragment
context = getContext(); context = getContext();
setStyle(STYLE_NO_TITLE, ThemeHelper.getDialogTheme(context)); setStyle(STYLE_NO_TITLE, ThemeHelper.getDialogTheme(context));
Icepick.restoreInstanceState(this, savedInstanceState); Bridge.restoreInstanceState(this, savedInstanceState);
this.audioTrackAdapter = new AudioTrackAdapter(wrappedAudioTracks); this.audioTrackAdapter = new AudioTrackAdapter(wrappedAudioTracks);
this.subtitleStreamsAdapter = new StreamItemAdapter<>(wrappedSubtitleStreams); this.subtitleStreamsAdapter = new StreamItemAdapter<>(wrappedSubtitleStreams);
@ -372,7 +372,7 @@ public class DownloadDialog extends DialogFragment
@Override @Override
public void onSaveInstanceState(@NonNull final Bundle outState) { public void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState); Bridge.saveInstanceState(this, outState);
} }

View file

@ -13,6 +13,8 @@ import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.evernote.android.state.State;
import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.BaseFragment;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorInfo;
@ -22,8 +24,6 @@ import org.schabi.newpipe.util.InfoCache;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import icepick.State;
public abstract class BaseStateFragment<I> extends BaseFragment implements ViewContract<I> { public abstract class BaseStateFragment<I> extends BaseFragment implements ViewContract<I> {
@State @State
protected AtomicBoolean wasLoading = new AtomicBoolean(); protected AtomicBoolean wasLoading = new AtomicBoolean();
@ -134,6 +134,7 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
hideErrorPanel(); hideErrorPanel();
} }
@Override
public void showEmptyState() { public void showEmptyState() {
isLoading.set(false); isLoading.set(false);
if (emptyStateView != null) { if (emptyStateView != null) {

View file

@ -11,6 +11,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import com.evernote.android.state.State;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Description;
@ -19,8 +21,6 @@ import org.schabi.newpipe.util.Localization;
import java.util.List; import java.util.List;
import icepick.State;
public class DescriptionFragment extends BaseDescriptionFragment { public class DescriptionFragment extends BaseDescriptionFragment {
@State @State
@ -31,7 +31,7 @@ public class DescriptionFragment extends BaseDescriptionFragment {
} }
public DescriptionFragment() { public DescriptionFragment() {
// keep empty constructor for IcePick when resuming fragment from memory // keep empty constructor for State when resuming fragment from memory
} }

View file

@ -56,6 +56,7 @@ import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.evernote.android.state.State;
import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.AppBarLayout;
@ -127,7 +128,6 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.disposables.Disposable;

View file

@ -9,6 +9,8 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.state.State;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.error.UserAction;
@ -24,7 +26,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.disposables.Disposable;
@ -143,7 +144,7 @@ public abstract class BaseListInfoFragment<I extends InfoItem, L extends ListInf
currentWorker = loadResult(forceLoad) currentWorker = loadResult(forceLoad)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe((@NonNull L result) -> { .subscribe((@NonNull final L result) -> {
isLoading.set(false); isLoading.set(false);
currentInfo = result; currentInfo = result;
currentNextPage = result.getNextPage(); currentNextPage = result.getNextPage();

View file

@ -10,6 +10,8 @@ import android.widget.LinearLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.evernote.android.state.State;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfo;
@ -20,8 +22,6 @@ import org.schabi.newpipe.util.Localization;
import java.util.List; import java.util.List;
import icepick.State;
public class ChannelAboutFragment extends BaseDescriptionFragment { public class ChannelAboutFragment extends BaseDescriptionFragment {
@State @State
protected ChannelInfo channelInfo; protected ChannelInfo channelInfo;
@ -31,7 +31,7 @@ public class ChannelAboutFragment extends BaseDescriptionFragment {
} }
public ChannelAboutFragment() { public ChannelAboutFragment() {
// keep empty constructor for IcePick when resuming fragment from memory // keep empty constructor for State when resuming fragment from memory
} }
@Override @Override

View file

@ -25,6 +25,7 @@ import androidx.core.graphics.ColorUtils;
import androidx.core.view.MenuProvider; import androidx.core.view.MenuProvider;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.evernote.android.state.State;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.jakewharton.rxbinding4.view.RxView; import com.jakewharton.rxbinding4.view.RxView;
@ -50,16 +51,15 @@ import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.StateSaver;
import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PicassoHelper;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
@ -249,7 +249,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private void monitorSubscription(final ChannelInfo info) { private void monitorSubscription(final ChannelInfo info) {
final Consumer<Throwable> onError = (Throwable throwable) -> { final Consumer<Throwable> onError = (final Throwable throwable) -> {
animate(binding.channelSubscribeButton, false, 100); animate(binding.channelSubscribeButton, false, 100);
showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_GET, showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_GET,
"Get subscription status", currentInfo)); "Get subscription status", currentInfo));
@ -284,14 +284,14 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
} }
private Function<Object, Object> mapOnSubscribe(final SubscriptionEntity subscription) { private Function<Object, Object> mapOnSubscribe(final SubscriptionEntity subscription) {
return (@NonNull Object o) -> { return (@NonNull final Object o) -> {
subscriptionManager.insertSubscription(subscription); subscriptionManager.insertSubscription(subscription);
return o; return o;
}; };
} }
private Function<Object, Object> mapOnUnsubscribe(final SubscriptionEntity subscription) { private Function<Object, Object> mapOnUnsubscribe(final SubscriptionEntity subscription) {
return (@NonNull Object o) -> { return (@NonNull final Object o) -> {
subscriptionManager.deleteSubscription(subscription); subscriptionManager.deleteSubscription(subscription);
return o; return o;
}; };
@ -318,7 +318,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
} }
private Disposable monitorSubscribeButton(final Function<Object, Object> action) { private Disposable monitorSubscribeButton(final Function<Object, Object> action) {
final Consumer<Object> onNext = (@NonNull Object o) -> { final Consumer<Object> onNext = (@NonNull final Object o) -> {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Changed subscription status to this channel!"); Log.d(TAG, "Changed subscription status to this channel!");
} }
@ -338,7 +338,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
} }
private Consumer<List<SubscriptionEntity>> getSubscribeUpdateMonitor(final ChannelInfo info) { private Consumer<List<SubscriptionEntity>> getSubscribeUpdateMonitor(final ChannelInfo info) {
return (List<SubscriptionEntity> subscriptionEntities) -> { return (final List<SubscriptionEntity> subscriptionEntities) -> {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "subscriptionManager.subscriptionTable.doOnNext() called with: " Log.d(TAG, "subscriptionManager.subscriptionTable.doOnNext() called with: "
+ "subscriptionEntities = [" + subscriptionEntities + "]"); + "subscriptionEntities = [" + subscriptionEntities + "]");

View file

@ -9,6 +9,8 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.evernote.android.state.State;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.PlaylistControlBinding; import org.schabi.newpipe.databinding.PlaylistControlBinding;
import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.error.UserAction;
@ -32,13 +34,12 @@ import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import icepick.State;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTabInfo> public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTabInfo>
implements PlaylistControlViewHolder { implements PlaylistControlViewHolder {
// states must be protected and not private for IcePick being able to access them // states must be protected and not private for State being able to access them
@State @State
protected ListLinkHandler tabHandler; protected ListLinkHandler tabHandler;
@State @State
@ -156,6 +157,7 @@ public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTa
} }
} }
@Override
public PlayQueue getPlayQueue() { public PlayQueue getPlayQueue() {
final List<StreamInfoItem> streamItems = infoListAdapter.getItemsList().stream() final List<StreamInfoItem> streamItems = infoListAdapter.getItemsList().stream()
.filter(StreamInfoItem.class::isInstance) .filter(StreamInfoItem.class::isInstance)

View file

@ -12,6 +12,8 @@ import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.text.HtmlCompat; import androidx.core.text.HtmlCompat;
import com.evernote.android.state.State;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.CommentRepliesHeaderBinding; import org.schabi.newpipe.databinding.CommentRepliesHeaderBinding;
import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.error.UserAction;
@ -30,7 +32,6 @@ import org.schabi.newpipe.util.text.TextLinkifier;
import java.util.Queue; import java.util.Queue;
import java.util.function.Supplier; import java.util.function.Supplier;
import icepick.State;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;

View file

@ -11,6 +11,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import com.evernote.android.state.State;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.error.UserAction;
@ -29,7 +31,6 @@ import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.KioskTranslator; import org.schabi.newpipe.util.KioskTranslator;
import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.Localization;
import icepick.State;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
/** /**

View file

@ -40,6 +40,8 @@ import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.evernote.android.state.State;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.FragmentSearchBinding; import org.schabi.newpipe.databinding.FragmentSearchBinding;
import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorInfo;
@ -77,7 +79,6 @@ import java.util.Queue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
@ -550,7 +551,7 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
} }
}); });
searchEditText.setOnFocusChangeListener((View v, boolean hasFocus) -> { searchEditText.setOnFocusChangeListener((final View v, final boolean hasFocus) -> {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onFocusChange() called with: " Log.d(TAG, "onFocusChange() called with: "
+ "v = [" + v + "], hasFocus = [" + hasFocus + "]"); + "v = [" + v + "], hasFocus = [" + hasFocus + "]");
@ -611,7 +612,7 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
}; };
searchEditText.addTextChangedListener(textWatcher); searchEditText.addTextChangedListener(textWatcher);
searchEditText.setOnEditorActionListener( searchEditText.setOnEditorActionListener(
(TextView v, int actionId, KeyEvent event) -> { (final TextView v, final int actionId, final KeyEvent event) -> {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onEditorAction() called with: v = [" + v + "], " Log.d(TAG, "onEditorAction() called with: v = [" + v + "], "
+ "actionId = [" + actionId + "], event = [" + event + "]"); + "actionId = [" + actionId + "], event = [" + event + "]");

View file

@ -19,6 +19,8 @@ import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.evernote.android.state.State;
import org.reactivestreams.Subscriber; import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription; import org.reactivestreams.Subscription;
import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.NewPipeDatabase;
@ -36,16 +38,15 @@ import org.schabi.newpipe.local.holder.LocalBookmarkPlaylistItemHolder;
import org.schabi.newpipe.local.holder.RemoteBookmarkPlaylistItemHolder; import org.schabi.newpipe.local.holder.RemoteBookmarkPlaylistItemHolder;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager; import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager; import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
import org.schabi.newpipe.util.debounce.DebounceSavable;
import org.schabi.newpipe.util.debounce.DebounceSaver;
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.debounce.DebounceSavable;
import org.schabi.newpipe.util.debounce.DebounceSaver;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.disposables.Disposable;

View file

@ -44,11 +44,11 @@ import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.evernote.android.state.State
import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.GroupieAdapter
import com.xwray.groupie.Item import com.xwray.groupie.Item
import com.xwray.groupie.OnItemClickListener import com.xwray.groupie.OnItemClickListener
import com.xwray.groupie.OnItemLongClickListener import com.xwray.groupie.OnItemLongClickListener
import icepick.State
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable

View file

@ -15,6 +15,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.viewbinding.ViewBinding; import androidx.viewbinding.ViewBinding;
import com.evernote.android.state.State;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import org.reactivestreams.Subscriber; import org.reactivestreams.Subscriber;
@ -45,7 +46,6 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.disposables.Disposable;
@ -368,6 +368,7 @@ public class StatisticsPlaylistFragment
} }
} }
@Override
public PlayQueue getPlayQueue() { public PlayQueue getPlayQueue() {
return getPlayQueue(0); return getPlayQueue(0);
} }

View file

@ -26,6 +26,8 @@ import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding; import androidx.viewbinding.ViewBinding;
import com.evernote.android.state.State;
import org.reactivestreams.Subscriber; import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription; import org.reactivestreams.Subscription;
import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.NewPipeDatabase;
@ -49,12 +51,12 @@ import org.schabi.newpipe.local.BaseLocalListFragment;
import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.util.debounce.DebounceSavable;
import org.schabi.newpipe.util.debounce.DebounceSaver;
import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.Localization;
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.PlayButtonHelper; import org.schabi.newpipe.util.PlayButtonHelper;
import org.schabi.newpipe.util.debounce.DebounceSavable;
import org.schabi.newpipe.util.debounce.DebounceSaver;
import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.external_communication.ShareUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -63,7 +65,6 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
@ -843,6 +844,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
} }
} }
@Override
public PlayQueue getPlayQueue() { public PlayQueue getPlayQueue() {
return getPlayQueue(0); return getPlayQueue(0);
} }

View file

@ -1,5 +1,7 @@
package org.schabi.newpipe.local.subscription; package org.schabi.newpipe.local.subscription;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import android.app.Dialog; import android.app.Dialog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -10,13 +12,11 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.evernote.android.state.State;
import com.livefront.bridge.Bridge;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import icepick.Icepick;
import icepick.State;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
public class ImportConfirmationDialog extends DialogFragment { public class ImportConfirmationDialog extends DialogFragment {
@State @State
protected Intent resultServiceIntent; protected Intent resultServiceIntent;
@ -57,12 +57,12 @@ public class ImportConfirmationDialog extends DialogFragment {
throw new IllegalStateException("Result intent is null"); throw new IllegalStateException("Result intent is null");
} }
Icepick.restoreInstanceState(this, savedInstanceState); Bridge.restoreInstanceState(this, savedInstanceState);
} }
@Override @Override
public void onSaveInstanceState(@NonNull final Bundle outState) { public void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState); Bridge.saveInstanceState(this, outState);
} }
} }

View file

@ -20,11 +20,11 @@ import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.evernote.android.state.State
import com.xwray.groupie.Group import com.xwray.groupie.Group
import com.xwray.groupie.GroupAdapter import com.xwray.groupie.GroupAdapter
import com.xwray.groupie.Section import com.xwray.groupie.Section
import com.xwray.groupie.viewbinding.GroupieViewHolder import com.xwray.groupie.viewbinding.GroupieViewHolder
import icepick.State
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.GROUP_ALL_ID import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.GROUP_ALL_ID

View file

@ -27,6 +27,8 @@ import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.core.text.util.LinkifyCompat; import androidx.core.text.util.LinkifyCompat;
import com.evernote.android.state.State;
import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.BaseFragment;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorInfo;
@ -44,8 +46,6 @@ import org.schabi.newpipe.util.ServiceHelper;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import icepick.State;
public class SubscriptionsImportFragment extends BaseFragment { public class SubscriptionsImportFragment extends BaseFragment {
@State @State
int currentServiceId = Constants.NO_SERVICE_ID; int currentServiceId = Constants.NO_SERVICE_ID;

View file

@ -18,11 +18,11 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.evernote.android.state.State
import com.livefront.bridge.Bridge
import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.GroupieAdapter
import com.xwray.groupie.OnItemClickListener import com.xwray.groupie.OnItemClickListener
import com.xwray.groupie.Section import com.xwray.groupie.Section
import icepick.Icepick
import icepick.State
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.databinding.DialogFeedGroupCreateBinding import org.schabi.newpipe.databinding.DialogFeedGroupCreateBinding
@ -78,7 +78,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Icepick.restoreInstanceState(this, savedInstanceState) Bridge.restoreInstanceState(this, savedInstanceState)
setStyle(STYLE_NO_TITLE, ThemeHelper.getMinWidthDialogTheme(requireContext())) setStyle(STYLE_NO_TITLE, ThemeHelper.getMinWidthDialogTheme(requireContext()))
groupId = arguments?.getLong(KEY_GROUP_ID, NO_GROUP_SELECTED) ?: NO_GROUP_SELECTED groupId = arguments?.getLong(KEY_GROUP_ID, NO_GROUP_SELECTED) ?: NO_GROUP_SELECTED
@ -114,7 +114,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
iconsListState = feedGroupCreateBinding.iconSelector.layoutManager?.onSaveInstanceState() iconsListState = feedGroupCreateBinding.iconSelector.layoutManager?.onSaveInstanceState()
subscriptionsListState = feedGroupCreateBinding.subscriptionsSelectorList.layoutManager?.onSaveInstanceState() subscriptionsListState = feedGroupCreateBinding.subscriptionsSelectorList.layoutManager?.onSaveInstanceState()
Icepick.saveInstanceState(this, outState) Bridge.saveInstanceState(this, outState)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View file

@ -11,10 +11,10 @@ import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback import androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.evernote.android.state.State
import com.livefront.bridge.Bridge
import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.GroupieAdapter
import com.xwray.groupie.TouchCallback import com.xwray.groupie.TouchCallback
import icepick.Icepick
import icepick.State
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.databinding.DialogFeedGroupReorderBinding import org.schabi.newpipe.databinding.DialogFeedGroupReorderBinding
@ -23,10 +23,6 @@ import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialogViewMo
import org.schabi.newpipe.local.subscription.item.FeedGroupReorderItem import org.schabi.newpipe.local.subscription.item.FeedGroupReorderItem
import org.schabi.newpipe.util.ThemeHelper import org.schabi.newpipe.util.ThemeHelper
import java.util.Collections import java.util.Collections
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.map
import kotlin.collections.sortedBy
class FeedGroupReorderDialog : DialogFragment() { class FeedGroupReorderDialog : DialogFragment() {
private var _binding: DialogFeedGroupReorderBinding? = null private var _binding: DialogFeedGroupReorderBinding? = null
@ -42,7 +38,7 @@ class FeedGroupReorderDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Icepick.restoreInstanceState(this, savedInstanceState) Bridge.restoreInstanceState(this, savedInstanceState)
setStyle(STYLE_NO_TITLE, ThemeHelper.getMinWidthDialogTheme(requireContext())) setStyle(STYLE_NO_TITLE, ThemeHelper.getMinWidthDialogTheme(requireContext()))
} }
@ -80,7 +76,7 @@ class FeedGroupReorderDialog : DialogFragment() {
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
Icepick.saveInstanceState(this, outState) Bridge.saveInstanceState(this, outState)
} }
private fun handleGroups(list: List<FeedGroupEntity>) { private fun handleGroups(list: List<FeedGroupEntity>) {

View file

@ -24,6 +24,9 @@ import androidx.core.math.MathUtils;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.evernote.android.state.State;
import com.livefront.bridge.Bridge;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.DialogPlaybackParameterBinding; import org.schabi.newpipe.databinding.DialogPlaybackParameterBinding;
import org.schabi.newpipe.player.ui.VideoPlayerUi; import org.schabi.newpipe.player.ui.VideoPlayerUi;
@ -37,9 +40,6 @@ import java.util.function.DoubleConsumer;
import java.util.function.DoubleFunction; import java.util.function.DoubleFunction;
import java.util.function.DoubleSupplier; import java.util.function.DoubleSupplier;
import icepick.Icepick;
import icepick.State;
public class PlaybackParameterDialog extends DialogFragment { public class PlaybackParameterDialog extends DialogFragment {
private static final String TAG = "PlaybackParameterDialog"; private static final String TAG = "PlaybackParameterDialog";
@ -135,7 +135,7 @@ public class PlaybackParameterDialog extends DialogFragment {
@Override @Override
public void onSaveInstanceState(@NonNull final Bundle outState) { public void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState); Bridge.saveInstanceState(this, outState);
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -146,7 +146,7 @@ public class PlaybackParameterDialog extends DialogFragment {
@Override @Override
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) { public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
assureCorrectAppLanguage(getContext()); assureCorrectAppLanguage(getContext());
Icepick.restoreInstanceState(this, savedInstanceState); Bridge.restoreInstanceState(this, savedInstanceState);
binding = DialogPlaybackParameterBinding.inflate(getLayoutInflater()); binding = DialogPlaybackParameterBinding.inflate(getLayoutInflater());
initUI(); initUI();

View file

@ -21,7 +21,9 @@ import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
import com.evernote.android.state.State;
import com.jakewharton.rxbinding4.widget.RxTextView; import com.jakewharton.rxbinding4.widget.RxTextView;
import com.livefront.bridge.Bridge;
import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
@ -41,9 +43,6 @@ import org.schabi.newpipe.views.FocusOverlayView;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import icepick.Icepick;
import icepick.State;
/* /*
* Created by Christian Schabesberger on 31.08.15. * Created by Christian Schabesberger on 31.08.15.
* *
@ -93,7 +92,7 @@ public class SettingsActivity extends AppCompatActivity implements
assureCorrectAppLanguage(this); assureCorrectAppLanguage(this);
super.onCreate(savedInstanceBundle); super.onCreate(savedInstanceBundle);
Icepick.restoreInstanceState(this, savedInstanceBundle); Bridge.restoreInstanceState(this, savedInstanceBundle);
final boolean restored = savedInstanceBundle != null; final boolean restored = savedInstanceBundle != null;
final SettingsLayoutBinding settingsLayoutBinding = final SettingsLayoutBinding settingsLayoutBinding =
@ -125,7 +124,7 @@ public class SettingsActivity extends AppCompatActivity implements
@Override @Override
protected void onSaveInstanceState(@NonNull final Bundle outState) { protected void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState); Bridge.saveInstanceState(this, outState);
} }
@Override @Override

View file

@ -0,0 +1,61 @@
package org.schabi.newpipe.util;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.evernote.android.state.StateSaver;
import com.livefront.bridge.Bridge;
import com.livefront.bridge.SavedStateHandler;
import com.livefront.bridge.ViewSavedStateHandler;
/**
* Configures Bridge's state saver.
*/
public final class BridgeStateSaverInitializer {
public static void init(final Context context) {
Bridge.initialize(
context,
new SavedStateHandler() {
@Override
public void saveInstanceState(
@NonNull final Object target,
@NonNull final Bundle state) {
StateSaver.saveInstanceState(target, state);
}
@Override
public void restoreInstanceState(
@NonNull final Object target,
@Nullable final Bundle state) {
StateSaver.restoreInstanceState(target, state);
}
},
new ViewSavedStateHandler() {
@NonNull
@Override
public <T extends View> Parcelable saveInstanceState(
@NonNull final T target,
@Nullable final Parcelable parentState) {
return StateSaver.saveInstanceState(target, parentState);
}
@Nullable
@Override
public <T extends View> Parcelable restoreInstanceState(
@NonNull final T target,
@Nullable final Parcelable state) {
return StateSaver.restoreInstanceState(target, state);
}
}
);
}
private BridgeStateSaverInitializer() {
}
}

View file

@ -19,6 +19,9 @@
package org.schabi.newpipe.views; package org.schabi.newpipe.views;
import static org.schabi.newpipe.MainActivity.DEBUG;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.os.Parcelable; import android.os.Parcelable;
@ -29,18 +32,15 @@ import android.widget.LinearLayout;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.evernote.android.state.State;
import com.livefront.bridge.Bridge;
import org.schabi.newpipe.ktx.ViewUtils; import org.schabi.newpipe.ktx.ViewUtils;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import icepick.Icepick;
import icepick.State;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import static org.schabi.newpipe.MainActivity.DEBUG;
/** /**
* A view that can be fully collapsed and expanded. * A view that can be fully collapsed and expanded.
*/ */
@ -207,12 +207,12 @@ public class CollapsibleView extends LinearLayout {
@Nullable @Nullable
@Override @Override
public Parcelable onSaveInstanceState() { public Parcelable onSaveInstanceState() {
return Icepick.saveInstanceState(this, super.onSaveInstanceState()); return Bridge.saveInstanceState(this, super.onSaveInstanceState());
} }
@Override @Override
public void onRestoreInstanceState(final Parcelable state) { public void onRestoreInstanceState(final Parcelable state) {
super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state)); super.onRestoreInstanceState(Bridge.restoreInstanceState(this, state));
ready(); ready();
} }

View file

@ -1 +0,0 @@
../layout/list_stream_item.xml

View file

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/itemRoot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/video_item_search_padding">
<ImageView
android:id="@+id/itemThumbnailView"
android:layout_width="@dimen/video_item_search_thumbnail_image_width"
android:layout_height="@dimen/video_item_search_thumbnail_image_height"
android:scaleType="fitCenter"
android:src="@drawable/placeholder_thumbnail_video"
app:layout_constraintBottom_toTopOf="@+id/itemProgressView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/itemDurationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/video_item_search_duration_margin"
android:layout_marginBottom="@dimen/video_item_search_duration_margin"
android:background="@color/duration_background_color"
android:paddingHorizontal="@dimen/video_item_search_duration_horizontal_padding"
android:paddingVertical="@dimen/video_item_search_duration_vertical_padding"
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/duration_text_color"
android:textSize="@dimen/video_item_search_duration_text_size"
app:layout_constraintBottom_toBottomOf="@id/itemThumbnailView"
app:layout_constraintRight_toRightOf="@id/itemThumbnailView"
tools:text="1:09:10" />
<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/itemVideoTitleView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/video_item_search_image_right_margin"
android:ellipsize="end"
android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_search_title_text_size"
app:layout_constraintBottom_toTopOf="@+id/itemUploaderView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/itemThumbnailView"
app:layout_constraintTop_toTopOf="parent"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum" />
<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/itemUploaderView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_uploader_text_size"
app:layout_constraintBottom_toTopOf="@+id/itemAdditionalDetails"
app:layout_constraintEnd_toEndOf="@+id/itemVideoTitleView"
app:layout_constraintStart_toStartOf="@+id/itemVideoTitleView"
app:layout_constraintTop_toBottomOf="@+id/itemVideoTitleView"
tools:text="Uploader" />
<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/itemAdditionalDetails"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_upload_date_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/itemVideoTitleView"
app:layout_constraintStart_toStartOf="@+id/itemVideoTitleView"
app:layout_constraintTop_toBottomOf="@+id/itemUploaderView"
tools:text="2 years ago • 10M views" />
<org.schabi.newpipe.views.AnimatedProgressBar
android:id="@+id/itemProgressView"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="4dp"
android:progressDrawable="?progress_horizontal_drawable"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/itemThumbnailView"
app:layout_constraintStart_toStartOf="@+id/itemThumbnailView"
app:layout_constraintTop_toBottomOf="@+id/itemThumbnailView" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.9.10' ext.kotlin_version = '1.9.25'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.2.0' classpath 'com.android.tools.build:gradle:8.7.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View file

@ -1,4 +1,3 @@
android.defaults.buildfeatures.buildconfig=true
android.enableJetifier=false android.enableJetifier=false
android.nonFinalResIds=false android.nonFinalResIds=false
android.nonTransitiveRClass=true android.nonTransitiveRClass=true

View file

@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=38f66cd6eef217b4c35855bb11ea4e9fbc53594ccccb5fb82dfd317ef8c2c5a3 distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000 networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists