Skip to content

Commit 1f2e579

Browse files
Merge branch 'dev' into Merge-dev-to-refactor
# Conflicts: # app/build.gradle # app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java # app/src/main/res/values/strings.xml
2 parents f938062 + 0db859e commit 1f2e579

29 files changed

+170
-142
lines changed

README.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,8 @@
99

1010
<p align="center">
1111
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub NewPipe releases"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
12-
<a href="https://github.com/TeamNewPipe/NewPipe-nightly/releases" alt="GitHub NewPipe nightly releases">
13-
<img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-nightly.svg?labelColor=purple&label=dev%20nightly" >
14-
</a>
15-
<a href="https://github.com/TeamNewPipe/NewPipe-refactor-nightly/releases" alt="GitHub NewPipe refactor nightly releases">
16-
<img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-refactor-nightly.svg?labelColor=purple&label=refactor%20nightly" >
17-
</a>
12+
<a href="https://github.com/TeamNewPipe/NewPipe-nightly/releases" alt="GitHub NewPipe nightly releases"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-nightly.svg?labelColor=purple&label=dev%20nightly"></a>
13+
<a href="https://github.com/TeamNewPipe/NewPipe-refactor-nightly/releases" alt="GitHub NewPipe refactor nightly releases"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-refactor-nightly.svg?labelColor=purple&label=refactor%20nightly"></a>
1814
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
1915
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/actions/workflows/ci.yml/badge.svg?branch=dev&event=push"></a>
2016
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>

app/src/main/java/org/schabi/newpipe/MainActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import org.schabi.newpipe.player.event.OnKeyDownListener;
7777
import org.schabi.newpipe.player.helper.PlayerHolder;
7878
import org.schabi.newpipe.player.playqueue.PlayQueue;
79+
import org.schabi.newpipe.settings.SettingMigrations;
7980
import org.schabi.newpipe.settings.UpdateSettingsFragment;
8081
import org.schabi.newpipe.util.Constants;
8182
import org.schabi.newpipe.util.DeviceUtils;
@@ -193,6 +194,7 @@ protected void onCreate(final Bundle savedInstanceState) {
193194
}
194195

195196
Localization.migrateAppLanguageSettingIfNecessary(getApplicationContext());
197+
SettingMigrations.showUserInfoIfPresent(this);
196198
}
197199

198200
@Override

app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import java.util.concurrent.TimeUnit
3535
class ErrorPanelHelper(
3636
private val fragment: Fragment,
3737
rootView: View,
38-
onRetry: Runnable
38+
onRetry: Runnable?,
3939
) {
4040
private val context: Context = rootView.context!!
4141

@@ -56,12 +56,15 @@ class ErrorPanelHelper(
5656
errorPanelRoot.findViewById(R.id.error_open_in_browser)
5757

5858
private var errorDisposable: Disposable? = null
59+
private var retryShouldBeShown: Boolean = (onRetry != null)
5960

6061
init {
61-
errorDisposable = errorRetryButton.clicks()
62-
.debounce(300, TimeUnit.MILLISECONDS)
63-
.observeOn(AndroidSchedulers.mainThread())
64-
.subscribe { onRetry.run() }
62+
if (onRetry != null) {
63+
errorDisposable = errorRetryButton.clicks()
64+
.debounce(300, TimeUnit.MILLISECONDS)
65+
.observeOn(AndroidSchedulers.mainThread())
66+
.subscribe { onRetry.run() }
67+
}
6568
}
6669

6770
private fun ensureDefaultVisibility() {
@@ -101,7 +104,7 @@ class ErrorPanelHelper(
101104
errorActionButton.setOnClickListener(null)
102105
}
103106

104-
errorRetryButton.isVisible = true
107+
errorRetryButton.isVisible = retryShouldBeShown
105108
showAndSetOpenInBrowserButtonAction(errorInfo)
106109
} else if (errorInfo.throwable is AccountTerminatedException) {
107110
errorTextView.setText(R.string.account_terminated)
@@ -130,7 +133,7 @@ class ErrorPanelHelper(
130133
errorInfo.throwable !is ContentNotSupportedException
131134
) {
132135
// show retry button only for content which is not unavailable or unsupported
133-
errorRetryButton.isVisible = true
136+
errorRetryButton.isVisible = retryShouldBeShown
134137
}
135138
showAndSetOpenInBrowserButtonAction(errorInfo)
136139
}

app/src/main/java/org/schabi/newpipe/error/UserAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public enum UserAction {
3232
PREFERENCES_MIGRATION("migration of preferences"),
3333
SHARE_TO_NEWPIPE("share to newpipe"),
3434
CHECK_FOR_NEW_APP_VERSION("check for new app version"),
35-
OPEN_INFO_ITEM_DIALOG("open info item dialog");
35+
OPEN_INFO_ITEM_DIALOG("open info item dialog"),
36+
GETTING_MAIN_SCREEN_TAB("getting main screen tab");
3637

3738
private final String message;
3839

app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,57 @@
77

88
import androidx.annotation.Nullable;
99

10+
import com.evernote.android.state.State;
11+
1012
import org.schabi.newpipe.BaseFragment;
1113
import org.schabi.newpipe.R;
14+
import org.schabi.newpipe.error.ErrorInfo;
15+
import org.schabi.newpipe.error.ErrorPanelHelper;
1216

1317
public class BlankFragment extends BaseFragment {
18+
19+
@State
20+
@Nullable
21+
ErrorInfo errorInfo;
22+
@Nullable
23+
ErrorPanelHelper errorPanel = null;
24+
25+
/**
26+
* Builds a blank fragment that just says the app name and suggests clicking on search.
27+
*/
28+
public BlankFragment() {
29+
this(null);
30+
}
31+
32+
/**
33+
* @param errorInfo if null acts like {@link BlankFragment}, else shows an error panel.
34+
*/
35+
public BlankFragment(@Nullable final ErrorInfo errorInfo) {
36+
this.errorInfo = errorInfo;
37+
}
38+
1439
@Nullable
1540
@Override
1641
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
1742
final Bundle savedInstanceState) {
1843
setTitle("NewPipe");
19-
return inflater.inflate(R.layout.fragment_blank, container, false);
44+
final View view = inflater.inflate(R.layout.fragment_blank, container, false);
45+
if (errorInfo != null) {
46+
errorPanel = new ErrorPanelHelper(this, view, null);
47+
errorPanel.showError(errorInfo);
48+
view.findViewById(R.id.blank_page_content).setVisibility(View.GONE);
49+
}
50+
return view;
51+
}
52+
53+
@Override
54+
public void onDestroyView() {
55+
super.onDestroyView();
56+
57+
if (errorPanel != null) {
58+
errorPanel.dispose();
59+
errorPanel = null;
60+
}
2061
}
2162

2263
@Override

app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@
3636
import org.schabi.newpipe.BaseFragment;
3737
import org.schabi.newpipe.R;
3838
import org.schabi.newpipe.databinding.FragmentMainBinding;
39+
import org.schabi.newpipe.error.ErrorInfo;
3940
import org.schabi.newpipe.error.ErrorUtil;
40-
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
41+
import org.schabi.newpipe.error.UserAction;
4142
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
4243
import org.schabi.newpipe.settings.tabs.Tab;
4344
import org.schabi.newpipe.settings.tabs.TabsManager;
@@ -303,9 +304,9 @@ public Fragment getItem(final int position) {
303304
final Fragment fragment;
304305
try {
305306
fragment = tab.getFragment(context);
306-
} catch (final ExtractionException e) {
307-
ErrorUtil.showUiErrorSnackbar(context, "Getting fragment item", e);
308-
return new BlankFragment();
307+
} catch (final Throwable t) {
308+
return new BlankFragment(new ErrorInfo(t, UserAction.GETTING_MAIN_SCREEN_TAB,
309+
"Tab " + tab.getClass().getSimpleName() + ":" + tab.getTabName(context)));
309310
}
310311

311312
if (fragment instanceof BaseFragment) {

app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
11
package org.schabi.newpipe.settings;
22

3-
import static org.schabi.newpipe.MainActivity.DEBUG;
4-
53
import android.content.Context;
64
import android.content.SharedPreferences;
75
import android.util.Log;
86

97
import androidx.annotation.NonNull;
8+
import androidx.appcompat.app.AlertDialog;
9+
import androidx.core.util.Consumer;
1010
import androidx.preference.PreferenceManager;
1111

1212
import org.schabi.newpipe.App;
1313
import org.schabi.newpipe.R;
1414
import org.schabi.newpipe.error.ErrorInfo;
1515
import org.schabi.newpipe.error.ErrorUtil;
1616
import org.schabi.newpipe.error.UserAction;
17+
import org.schabi.newpipe.settings.tabs.Tab;
18+
import org.schabi.newpipe.settings.tabs.TabsManager;
1719
import org.schabi.newpipe.util.DeviceUtils;
1820

21+
import java.util.ArrayList;
1922
import java.util.Collections;
2023
import java.util.HashSet;
24+
import java.util.List;
2125
import java.util.Set;
26+
import java.util.stream.Collectors;
27+
28+
import static org.schabi.newpipe.MainActivity.DEBUG;
29+
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
2230

2331
/**
2432
* In order to add a migration, follow these steps, given P is the previous version:<br>
@@ -32,6 +40,12 @@ public final class SettingMigrations {
3240
private static final String TAG = SettingMigrations.class.toString();
3341
private static SharedPreferences sp;
3442

43+
/**
44+
* List of UI actions that are performed after the UI is initialized (e.g. showing alert
45+
* dialogs) to inform the user about changes that were applied by migrations.
46+
*/
47+
private static final List<Consumer<Context>> MIGRATION_INFO = new ArrayList<>();
48+
3549
private static final Migration MIGRATION_0_1 = new Migration(0, 1) {
3650
@Override
3751
public void migrate(@NonNull final Context context) {
@@ -129,7 +143,7 @@ protected void migrate(@NonNull final Context context) {
129143
}
130144
};
131145

132-
public static final Migration MIGRATION_5_6 = new Migration(5, 6) {
146+
private static final Migration MIGRATION_5_6 = new Migration(5, 6) {
133147
@Override
134148
protected void migrate(@NonNull final Context context) {
135149
final boolean loadImages = sp.getBoolean("download_thumbnail_key", true);
@@ -143,6 +157,32 @@ protected void migrate(@NonNull final Context context) {
143157
}
144158
};
145159

160+
private static final Migration MIGRATION_6_7 = new Migration(6, 7) {
161+
@Override
162+
protected void migrate(@NonNull final Context context) {
163+
// The SoundCloud Top 50 Kiosk was removed in the extractor,
164+
// so we remove the corresponding tab if it exists.
165+
final TabsManager tabsManager = TabsManager.getManager(context);
166+
final List<Tab> tabs = tabsManager.getTabs();
167+
final List<Tab> cleanedTabs = tabs.stream()
168+
.filter(tab -> !(tab instanceof Tab.KioskTab kioskTab
169+
&& kioskTab.getKioskServiceId() == SoundCloud.getServiceId()
170+
&& kioskTab.getKioskId().equals("Top 50")))
171+
.collect(Collectors.toUnmodifiableList());
172+
if (tabs.size() != cleanedTabs.size()) {
173+
tabsManager.saveTabs(cleanedTabs);
174+
// create an AlertDialog to inform the user about the change
175+
MIGRATION_INFO.add((Context uiContext) -> new AlertDialog.Builder(uiContext)
176+
.setTitle(R.string.migration_info_6_7_title)
177+
.setMessage(R.string.migration_info_6_7_message)
178+
.setPositiveButton(R.string.ok, null)
179+
.setCancelable(false)
180+
.create()
181+
.show());
182+
}
183+
}
184+
};
185+
146186
/**
147187
* List of all implemented migrations.
148188
* <p>
@@ -156,12 +196,13 @@ protected void migrate(@NonNull final Context context) {
156196
MIGRATION_3_4,
157197
MIGRATION_4_5,
158198
MIGRATION_5_6,
199+
MIGRATION_6_7
159200
};
160201

161202
/**
162203
* Version number for preferences. Must be incremented every time a migration is necessary.
163204
*/
164-
private static final int VERSION = 6;
205+
private static final int VERSION = 7;
165206

166207

167208
public static void runMigrationsIfNeeded(@NonNull final Context context) {
@@ -208,6 +249,21 @@ public static void runMigrationsIfNeeded(@NonNull final Context context) {
208249
sp.edit().putInt(lastPrefVersionKey, currentVersion).apply();
209250
}
210251

252+
/**
253+
* Perform UI actions informing about migrations that took place if they are present.
254+
* @param context Context that can be used to show dialogs/snackbars/toasts
255+
*/
256+
public static void showUserInfoIfPresent(@NonNull final Context context) {
257+
for (final Consumer<Context> consumer : MIGRATION_INFO) {
258+
try {
259+
consumer.accept(context);
260+
} catch (final Exception e) {
261+
ErrorUtil.showUiErrorSnackbar(context, "Showing migration info to the user", e);
262+
}
263+
}
264+
MIGRATION_INFO.clear();
265+
}
266+
211267
private SettingMigrations() { }
212268

213269
abstract static class Migration {

app/src/main/res/layout/fragment_blank.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
android:layout_width="match_parent"
55
android:layout_height="match_parent">
66

7-
<include layout="@layout/main_bg" />
7+
<include
8+
android:id="@+id/blank_page_content"
9+
layout="@layout/main_bg" />
810

911
<include
1012
android:id="@+id/error_panel"

app/src/main/res/values/strings.xml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,10 @@
397397
<string name="main_page_content">Content of main page</string>
398398
<string name="main_page_content_summary">What tabs are shown on the main page</string>
399399
<string name="main_page_content_swipe_remove">Swipe items to remove them</string>
400-
<string name="blank_page_summary">Blank Page</string>
401-
<string name="kiosk_page_summary">Kiosk Page</string>
400+
<string name="blank_page_summary">Blank page</string>
401+
<string name="kiosk_page_summary">Kiosk page</string>
402402
<string name="default_kiosk_page_summary">Default Kiosk</string>
403-
<string name="channel_page_summary">Channel Page</string>
403+
<string name="channel_page_summary">Channel page</string>
404404
<string name="select_a_channel">Select a channel</string>
405405
<string name="no_channel_subscribed_yet">No channel subscriptions yet</string>
406406
<string name="select_a_playlist">Select a playlist</string>
@@ -864,6 +864,8 @@
864864
<string name="show_more">Show more</string>
865865
<string name="show_less">Show less</string>
866866
<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>
867+
<string name="migration_info_6_7_title">SoundCloud Top 50 page removed</string>
868+
<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>
867869
<string name="auto_queue_description">Next</string>
868870
<string name="newpipe_extractor_description">NewPipeExtractor is a library for extracting things from streaming sites. It is a core component of NewPipe, but could be used independently.</string>
869871
<plurals name="comments">

doc/README.ar.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@
66

77
<p align="center">
88
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub release"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
9-
<a href="https://github.com/TeamNewPipe/NewPipe-nightly/releases" alt="GitHub NewPipe nightly releases">
10-
<img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-nightly.svg?labelColor=purple&label=dev%20nightly" >
11-
</a>
12-
<a href="https://github.com/TeamNewPipe/NewPipe-refactor-nightly/releases" alt="GitHub NewPipe refactor nightly releases">
13-
<img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-refactor-nightly.svg?labelColor=purple&label=refactor%20nightly" >
14-
</a>
9+
<a href="https://github.com/TeamNewPipe/NewPipe-nightly/releases" alt="GitHub NewPipe nightly releases"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-nightly.svg?labelColor=purple&label=dev%20nightly"></a>
10+
<a href="https://github.com/TeamNewPipe/NewPipe-refactor-nightly/releases" alt="GitHub NewPipe refactor nightly releases"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe-refactor-nightly.svg?labelColor=purple&label=refactor%20nightly"></a>
1511
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
1612
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/actions/workflows/ci.yml/badge.svg?branch=dev&event=push"></a>
1713
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>

0 commit comments

Comments
 (0)