mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-08-22 10:09:39 +00:00
Merge pull request #12438 from TeamNewPipe/soundcloud/top_50
This commit is contained in:
commit
0db859e225
@ -214,7 +214,7 @@ dependencies {
|
||||
// the corresponding commit hash, since JitPack sometimes deletes artifacts.
|
||||
// If there’s already a git hash, just add more of it to the end (or remove a letter)
|
||||
// to cause jitpack to regenerate the artifact.
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:68b4c9acbae2d167e7b1209bb6bf0ae086dd427e'
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:7adbc48a0aa872c016b8ec089e278d5e12772054'
|
||||
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
|
||||
|
||||
/** Checkstyle **/
|
||||
|
@ -80,6 +80,7 @@ import org.schabi.newpipe.player.Player;
|
||||
import org.schabi.newpipe.player.event.OnKeyDownListener;
|
||||
import org.schabi.newpipe.player.helper.PlayerHolder;
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||
import org.schabi.newpipe.settings.SettingMigrations;
|
||||
import org.schabi.newpipe.settings.UpdateSettingsFragment;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.DeviceUtils;
|
||||
@ -197,6 +198,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
Localization.migrateAppLanguageSettingIfNecessary(getApplicationContext());
|
||||
SettingMigrations.showUserInfoIfPresent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,7 +35,7 @@ import java.util.concurrent.TimeUnit
|
||||
class ErrorPanelHelper(
|
||||
private val fragment: Fragment,
|
||||
rootView: View,
|
||||
onRetry: Runnable
|
||||
onRetry: Runnable?,
|
||||
) {
|
||||
private val context: Context = rootView.context!!
|
||||
|
||||
@ -56,13 +56,16 @@ class ErrorPanelHelper(
|
||||
errorPanelRoot.findViewById(R.id.error_open_in_browser)
|
||||
|
||||
private var errorDisposable: Disposable? = null
|
||||
private var retryShouldBeShown: Boolean = (onRetry != null)
|
||||
|
||||
init {
|
||||
if (onRetry != null) {
|
||||
errorDisposable = errorRetryButton.clicks()
|
||||
.debounce(300, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { onRetry.run() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureDefaultVisibility() {
|
||||
errorTextView.isVisible = true
|
||||
@ -101,7 +104,7 @@ class ErrorPanelHelper(
|
||||
errorActionButton.setOnClickListener(null)
|
||||
}
|
||||
|
||||
errorRetryButton.isVisible = true
|
||||
errorRetryButton.isVisible = retryShouldBeShown
|
||||
showAndSetOpenInBrowserButtonAction(errorInfo)
|
||||
} else if (errorInfo.throwable is AccountTerminatedException) {
|
||||
errorTextView.setText(R.string.account_terminated)
|
||||
@ -130,7 +133,7 @@ class ErrorPanelHelper(
|
||||
errorInfo.throwable !is ContentNotSupportedException
|
||||
) {
|
||||
// show retry button only for content which is not unavailable or unsupported
|
||||
errorRetryButton.isVisible = true
|
||||
errorRetryButton.isVisible = retryShouldBeShown
|
||||
}
|
||||
showAndSetOpenInBrowserButtonAction(errorInfo)
|
||||
}
|
||||
|
@ -32,7 +32,8 @@ public enum UserAction {
|
||||
PREFERENCES_MIGRATION("migration of preferences"),
|
||||
SHARE_TO_NEWPIPE("share to newpipe"),
|
||||
CHECK_FOR_NEW_APP_VERSION("check for new app version"),
|
||||
OPEN_INFO_ITEM_DIALOG("open info item dialog");
|
||||
OPEN_INFO_ITEM_DIALOG("open info item dialog"),
|
||||
GETTING_MAIN_SCREEN_TAB("getting main screen tab");
|
||||
|
||||
private final String message;
|
||||
|
||||
|
@ -7,16 +7,57 @@ import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.evernote.android.state.State;
|
||||
|
||||
import org.schabi.newpipe.BaseFragment;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.ErrorPanelHelper;
|
||||
|
||||
public class BlankFragment extends BaseFragment {
|
||||
|
||||
@State
|
||||
@Nullable
|
||||
ErrorInfo errorInfo;
|
||||
@Nullable
|
||||
ErrorPanelHelper errorPanel = null;
|
||||
|
||||
/**
|
||||
* Builds a blank fragment that just says the app name and suggests clicking on search.
|
||||
*/
|
||||
public BlankFragment() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param errorInfo if null acts like {@link BlankFragment}, else shows an error panel.
|
||||
*/
|
||||
public BlankFragment(@Nullable final ErrorInfo errorInfo) {
|
||||
this.errorInfo = errorInfo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
setTitle("NewPipe");
|
||||
return inflater.inflate(R.layout.fragment_blank, container, false);
|
||||
final View view = inflater.inflate(R.layout.fragment_blank, container, false);
|
||||
if (errorInfo != null) {
|
||||
errorPanel = new ErrorPanelHelper(this, view, null);
|
||||
errorPanel.showError(errorInfo);
|
||||
view.findViewById(R.id.blank_page_content).setVisibility(View.GONE);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
||||
if (errorPanel != null) {
|
||||
errorPanel.dispose();
|
||||
errorPanel = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -36,8 +36,9 @@ import com.google.android.material.tabs.TabLayout;
|
||||
import org.schabi.newpipe.BaseFragment;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.databinding.FragmentMainBinding;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.ErrorUtil;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
|
||||
import org.schabi.newpipe.settings.tabs.Tab;
|
||||
import org.schabi.newpipe.settings.tabs.TabsManager;
|
||||
@ -303,9 +304,9 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
|
||||
final Fragment fragment;
|
||||
try {
|
||||
fragment = tab.getFragment(context);
|
||||
} catch (final ExtractionException e) {
|
||||
ErrorUtil.showUiErrorSnackbar(context, "Getting fragment item", e);
|
||||
return new BlankFragment();
|
||||
} catch (final Throwable t) {
|
||||
return new BlankFragment(new ErrorInfo(t, UserAction.GETTING_MAIN_SCREEN_TAB,
|
||||
"Tab " + tab.getClass().getSimpleName() + ":" + tab.getTabName(context)));
|
||||
}
|
||||
|
||||
if (fragment instanceof BaseFragment) {
|
||||
|
@ -5,6 +5,8 @@ import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.util.Consumer;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import org.schabi.newpipe.App;
|
||||
@ -12,13 +14,19 @@ import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.ErrorUtil;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.settings.tabs.Tab;
|
||||
import org.schabi.newpipe.settings.tabs.TabsManager;
|
||||
import org.schabi.newpipe.util.DeviceUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.schabi.newpipe.MainActivity.DEBUG;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
|
||||
|
||||
/**
|
||||
* In order to add a migration, follow these steps, given P is the previous version:<br>
|
||||
@ -32,6 +40,12 @@ public final class SettingMigrations {
|
||||
private static final String TAG = SettingMigrations.class.toString();
|
||||
private static SharedPreferences sp;
|
||||
|
||||
/**
|
||||
* List of UI actions that are performed after the UI is initialized (e.g. showing alert
|
||||
* dialogs) to inform the user about changes that were applied by migrations.
|
||||
*/
|
||||
private static final List<Consumer<Context>> MIGRATION_INFO = new ArrayList<>();
|
||||
|
||||
private static final Migration MIGRATION_0_1 = new Migration(0, 1) {
|
||||
@Override
|
||||
public void migrate(@NonNull final Context context) {
|
||||
@ -129,7 +143,7 @@ public final class SettingMigrations {
|
||||
}
|
||||
};
|
||||
|
||||
public static final Migration MIGRATION_5_6 = new Migration(5, 6) {
|
||||
private static final Migration MIGRATION_5_6 = new Migration(5, 6) {
|
||||
@Override
|
||||
protected void migrate(@NonNull final Context context) {
|
||||
final boolean loadImages = sp.getBoolean("download_thumbnail_key", true);
|
||||
@ -143,6 +157,32 @@ public final class SettingMigrations {
|
||||
}
|
||||
};
|
||||
|
||||
private static final Migration MIGRATION_6_7 = new Migration(6, 7) {
|
||||
@Override
|
||||
protected void migrate(@NonNull final Context context) {
|
||||
// The SoundCloud Top 50 Kiosk was removed in the extractor,
|
||||
// so we remove the corresponding tab if it exists.
|
||||
final TabsManager tabsManager = TabsManager.getManager(context);
|
||||
final List<Tab> tabs = tabsManager.getTabs();
|
||||
final List<Tab> cleanedTabs = tabs.stream()
|
||||
.filter(tab -> !(tab instanceof Tab.KioskTab kioskTab
|
||||
&& kioskTab.getKioskServiceId() == SoundCloud.getServiceId()
|
||||
&& kioskTab.getKioskId().equals("Top 50")))
|
||||
.collect(Collectors.toUnmodifiableList());
|
||||
if (tabs.size() != cleanedTabs.size()) {
|
||||
tabsManager.saveTabs(cleanedTabs);
|
||||
// create an AlertDialog to inform the user about the change
|
||||
MIGRATION_INFO.add((Context uiContext) -> new AlertDialog.Builder(uiContext)
|
||||
.setTitle(R.string.migration_info_6_7_title)
|
||||
.setMessage(R.string.migration_info_6_7_message)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setCancelable(false)
|
||||
.create()
|
||||
.show());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* List of all implemented migrations.
|
||||
* <p>
|
||||
@ -156,12 +196,13 @@ public final class SettingMigrations {
|
||||
MIGRATION_3_4,
|
||||
MIGRATION_4_5,
|
||||
MIGRATION_5_6,
|
||||
MIGRATION_6_7
|
||||
};
|
||||
|
||||
/**
|
||||
* Version number for preferences. Must be incremented every time a migration is necessary.
|
||||
*/
|
||||
private static final int VERSION = 6;
|
||||
private static final int VERSION = 7;
|
||||
|
||||
|
||||
public static void runMigrationsIfNeeded(@NonNull final Context context) {
|
||||
@ -208,6 +249,21 @@ public final class SettingMigrations {
|
||||
sp.edit().putInt(lastPrefVersionKey, currentVersion).apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform UI actions informing about migrations that took place if they are present.
|
||||
* @param context Context that can be used to show dialogs/snackbars/toasts
|
||||
*/
|
||||
public static void showUserInfoIfPresent(@NonNull final Context context) {
|
||||
for (final Consumer<Context> consumer : MIGRATION_INFO) {
|
||||
try {
|
||||
consumer.accept(context);
|
||||
} catch (final Exception e) {
|
||||
ErrorUtil.showUiErrorSnackbar(context, "Showing migration info to the user", e);
|
||||
}
|
||||
}
|
||||
MIGRATION_INFO.clear();
|
||||
}
|
||||
|
||||
private SettingMigrations() { }
|
||||
|
||||
abstract static class Migration {
|
||||
|
@ -4,7 +4,9 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/main_bg" />
|
||||
<include
|
||||
android:id="@+id/blank_page_content"
|
||||
layout="@layout/main_bg" />
|
||||
|
||||
<include
|
||||
android:id="@+id/error_panel"
|
||||
|
@ -865,4 +865,6 @@
|
||||
<string name="show_more">Show more</string>
|
||||
<string name="show_less">Show less</string>
|
||||
<string name="import_settings_vulnerable_format">The settings in the export being imported use a vulnerable format that was deprecated since NewPipe 0.27.0. Make sure the export being imported is from a trusted source, and prefer using only exports obtained from NewPipe 0.27.0 or newer in the future. Support for importing settings in this vulnerable format will soon be removed completely, and then old versions of NewPipe will not be able to import settings of exports from new versions anymore.</string>
|
||||
<string name="migration_info_6_7_title">SoundCloud Top 50 page removed</string>
|
||||
<string name="migration_info_6_7_message">SoundCloud has discontinued the original Top 50 charts. The corresponding tab has been removed from your main page.</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user