Skip to content

Commit 0e422a4

Browse files
Merge branch 'refactor' into History-Compose
2 parents 12a97c6 + 840084d commit 0e422a4

36 files changed

Lines changed: 757 additions & 73 deletions

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ jobs:
111111
path: app/build/reports/androidTests/connected/**
112112

113113
sonar:
114+
if: ${{ false }} # the key has expired and needs to be regenerated by the sonar admins
114115
runs-on: ubuntu-latest
115116

116117
permissions:

README.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
1-
<h3 align="center">We are planning to <i>rewrite</i> large chunks of the codebase, to bring about <a href="https://github.com/TeamNewPipe/NewPipe/discussions/10118">a new, modern and stable NewPipe</a>!</h3>
2-
<h4 align="center">Please do <b>not</b> open pull requests for <i>new features</i> now, only bugfix PRs will be accepted.</h4>
1+
<h3 align="center">We are <i>rewriting</i> large chunks of the codebase, to bring about <a href="https://newpipe.net/blog/pinned/announcement/newpipe-0.27.6-rewrite-team-states/#the-refactor">a modern and stable NewPipe</a>! You can download nightly builds <a href="https://github.com/TeamNewPipe/NewPipe-refactor-nightly/releases">here</a>.</h3>
2+
<h4 align="center">Please work on the <code>refactor</code> branch if you want to contribute <i>new features</i>. The current codebase is in maintenance mode and will only receive <i>bugfixes</i>.</h4>
33

44
<p align="center"><a href="https://newpipe.net"><img src="assets/new_pipe_icon_5.png" width="150"></a></p>
55
<h2 align="center"><b>NewPipe</b></h2>
66
<h4 align="center">A libre lightweight streaming front-end for Android.</h4>
77

8-
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-en.svg" alt="Get it on F-Droid" height=80/></a></p>
8+
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-en.svg" alt="Get it on F-Droid" width=206/></a></p>
99

1010
<p align="center">
11-
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub release"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
11+
<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>
1218
<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>
13-
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
19+
<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>
1420
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
21+
</p>
22+
23+
<p align="center">
1524
<a href="https://web.libera.chat/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
1625
<a href="https://matrix.to/#/#newpipe:matrix.newpipe-ev.de" alt="Matrix channel: #newpipe"><img src="https://img.shields.io/badge/Matrix%20chat-%23newpipe-blue"></a>
1726
</p>
27+
1828
<hr>
1929
<p align="center"><a href="#screenshots">Screenshots</a> &bull; <a href="#supported-services">Supported Services</a> &bull; <a href="#description">Description</a> &bull; <a href="#features">Features</a> &bull; <a href="#installation-and-updates">Installation and updates</a> &bull; <a href="#contribution">Contribution</a> &bull; <a href="#donate">Donate</a> &bull; <a href="#license">License</a></p>
2030
<p align="center"><a href="https://newpipe.net">Website</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">Press</a></p>

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

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ public class MainActivity extends AppCompatActivity {
122122
private static final int ITEM_ID_ABOUT = 2;
123123

124124
private static final int ORDER = 0;
125+
public static final String KEY_IS_IN_BACKGROUND = "is_in_background";
125126

127+
private SharedPreferences sharedPreferences;
128+
private SharedPreferences.Editor sharedPrefEditor;
126129
/*//////////////////////////////////////////////////////////////////////////
127130
// Activity's LifeCycle
128131
//////////////////////////////////////////////////////////////////////////*/
@@ -152,6 +155,8 @@ protected void onCreate(final Bundle savedInstanceState) {
152155

153156
assureCorrectAppLanguage(this);
154157
super.onCreate(savedInstanceState);
158+
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
159+
sharedPrefEditor = sharedPreferences.edit();
155160

156161
mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
157162
drawerLayoutBinding = mainBinding.drawerLayout;
@@ -195,16 +200,29 @@ protected void onPostCreate(final Bundle savedInstanceState) {
195200
super.onPostCreate(savedInstanceState);
196201

197202
final App app = App.getInstance();
198-
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
199203

200-
if (prefs.getBoolean(app.getString(R.string.update_app_key), false)
201-
&& prefs.getBoolean(app.getString(R.string.update_check_consent_key), false)) {
204+
if (sharedPreferences.getBoolean(app.getString(R.string.update_app_key), false)
205+
&& sharedPreferences
206+
.getBoolean(app.getString(R.string.update_check_consent_key), false)) {
202207
// Start the worker which is checking all conditions
203208
// and eventually searching for a new version.
204209
NewVersionWorker.enqueueNewVersionCheckingWork(app, false);
205210
}
206211
}
207212

213+
@Override
214+
protected void onStart() {
215+
super.onStart();
216+
sharedPrefEditor.putBoolean(KEY_IS_IN_BACKGROUND, false).apply();
217+
Log.d(TAG, "App moved to foreground");
218+
}
219+
220+
@Override
221+
protected void onStop() {
222+
super.onStop();
223+
sharedPrefEditor.putBoolean(KEY_IS_IN_BACKGROUND, true).apply();
224+
Log.d(TAG, "App moved to background");
225+
}
208226
private void setupDrawer() throws ExtractionException {
209227
addDrawerMenuForCurrentService();
210228

@@ -504,21 +522,19 @@ protected void onResume() {
504522
ErrorUtil.showUiErrorSnackbar(this, "Setting up service toggle", e);
505523
}
506524

507-
final SharedPreferences sharedPreferences =
508-
PreferenceManager.getDefaultSharedPreferences(this);
509525
if (sharedPreferences.getBoolean(Constants.KEY_THEME_CHANGE, false)) {
510526
if (DEBUG) {
511527
Log.d(TAG, "Theme has changed, recreating activity...");
512528
}
513-
sharedPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, false).apply();
529+
sharedPrefEditor.putBoolean(Constants.KEY_THEME_CHANGE, false).apply();
514530
ActivityCompat.recreate(this);
515531
}
516532

517533
if (sharedPreferences.getBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false)) {
518534
if (DEBUG) {
519535
Log.d(TAG, "main page has changed, recreating main fragment...");
520536
}
521-
sharedPreferences.edit().putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false).apply();
537+
sharedPrefEditor.putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false).apply();
522538
NavigationHelper.openMainActivity(this);
523539
}
524540

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import androidx.core.app.NotificationCompat
1111
import androidx.core.app.NotificationManagerCompat
1212
import androidx.core.app.PendingIntentCompat
1313
import androidx.fragment.app.Fragment
14+
import androidx.preference.PreferenceManager
1415
import com.google.android.material.snackbar.Snackbar
16+
import org.schabi.newpipe.MainActivity
1517
import org.schabi.newpipe.R
1618

1719
/**
@@ -35,12 +37,20 @@ class ErrorUtil {
3537
* activity (since the workflow would be interrupted anyway in that case). So never use this
3638
* for background services.
3739
*
40+
* If the crashed occurred while the app was in the background open a notification instead
41+
*
3842
* @param context the context to use to start the new activity
3943
* @param errorInfo the error info to be reported
4044
*/
4145
@JvmStatic
4246
fun openActivity(context: Context, errorInfo: ErrorInfo) {
43-
context.startActivity(getErrorActivityIntent(context, errorInfo))
47+
if (PreferenceManager.getDefaultSharedPreferences(context)
48+
.getBoolean(MainActivity.KEY_IS_IN_BACKGROUND, true)
49+
) {
50+
createNotification(context, errorInfo)
51+
} else {
52+
context.startActivity(getErrorActivityIntent(context, errorInfo))
53+
}
4454
}
4555

4656
/**

app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,12 @@ class FeedFragment : BaseStateFragment<FeedState>() {
274274
@Deprecated("Deprecated in Java")
275275
override fun onDestroyOptionsMenu() {
276276
super.onDestroyOptionsMenu()
277-
activity?.supportActionBar?.subtitle = null
277+
if (
278+
(groupName != "") &&
279+
(activity?.supportActionBar?.subtitle == groupName)
280+
) {
281+
activity?.supportActionBar?.subtitle = null
282+
}
278283
}
279284

280285
override fun onDestroy() {
@@ -286,7 +291,13 @@ class FeedFragment : BaseStateFragment<FeedState>() {
286291
}
287292

288293
super.onDestroy()
289-
activity?.supportActionBar?.subtitle = null
294+
295+
if (
296+
(groupName != "") &&
297+
(activity?.supportActionBar?.subtitle == groupName)
298+
) {
299+
activity?.supportActionBar?.subtitle = null
300+
}
290301
}
291302

292303
override fun onDestroyView() {

app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import android.view.MenuItem
1212
import android.view.SubMenu
1313
import android.view.View
1414
import android.view.ViewGroup
15+
import android.webkit.MimeTypeMap
1516
import android.widget.Toast
1617
import androidx.activity.result.ActivityResult
1718
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
@@ -456,6 +457,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
456457
}
457458

458459
companion object {
459-
const val JSON_MIME_TYPE = "application/json"
460+
val JSON_MIME_TYPE = MimeTypeMap.getSingleton()
461+
.getMimeTypeFromExtension("json") ?: "application/octet-stream"
460462
}
461463
}

app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ class PlayerServiceConnection implements ServiceConnection {
167167

168168
private boolean playAfterConnect = false;
169169

170+
/**
171+
* @param playAfterConnection Sets the value of `playAfterConnect` to pass to the {@link
172+
* PlayerServiceExtendedEventListener#onPlayerConnected(Player, boolean)} the next time it
173+
* is called. The value of `playAfterConnect` will be reset to false after that.
174+
*/
170175
public void doPlayAfterConnect(final boolean playAfterConnection) {
171176
this.playAfterConnect = playAfterConnection;
172177
}
@@ -371,6 +376,8 @@ public void onServiceStopped() {
371376
listener.onPlayerDisconnected();
372377
} else {
373378
listener.onPlayerConnected(player, serviceConnection.playAfterConnect);
379+
// reset the value of playAfterConnect: if it was true before, it is now "consumed"
380+
serviceConnection.playAfterConnect = false;
374381
player.setFragmentListener(internalListener);
375382
}
376383
}

app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import android.support.v4.media.MediaBrowserCompat
88
import android.support.v4.media.MediaDescriptionCompat
99
import android.util.Log
1010
import androidx.annotation.DrawableRes
11+
import androidx.core.net.toUri
1112
import androidx.media.MediaBrowserServiceCompat
1213
import androidx.media.MediaBrowserServiceCompat.Result
1314
import androidx.media.utils.MediaConstants
@@ -103,7 +104,7 @@ class MediaBrowserImpl(
103104

104105
private fun onLoadChildren(parentId: String): Single<List<MediaBrowserCompat.MediaItem>> {
105106
try {
106-
val parentIdUri = Uri.parse(parentId)
107+
val parentIdUri = parentId.toUri()
107108
val path = ArrayList(parentIdUri.pathSegments)
108109

109110
if (path.isEmpty()) {
@@ -185,7 +186,7 @@ class MediaBrowserImpl(
185186
builder
186187
.setMediaId(createMediaIdForInfoItem(playlist is PlaylistRemoteEntity, playlist.uid))
187188
.setTitle(playlist.orderingName)
188-
.setIconUri(playlist.thumbnailUrl?.let { Uri.parse(it) })
189+
.setIconUri(imageUriOrNullIfDisabled(playlist.thumbnailUrl))
189190

190191
val extras = Bundle()
191192
extras.putString(
@@ -212,7 +213,7 @@ class MediaBrowserImpl(
212213
}
213214

214215
ImageStrategy.choosePreferredImage(item.thumbnails)?.let {
215-
builder.setIconUri(Uri.parse(it))
216+
builder.setIconUri(imageUriOrNullIfDisabled(it))
216217
}
217218

218219
return MediaBrowserCompat.MediaItem(
@@ -258,7 +259,7 @@ class MediaBrowserImpl(
258259
builder.setMediaId(createMediaIdForPlaylistIndex(false, playlistId, index))
259260
.setTitle(item.streamEntity.title)
260261
.setSubtitle(item.streamEntity.uploader)
261-
.setIconUri(Uri.parse(item.streamEntity.thumbnailUrl))
262+
.setIconUri(imageUriOrNullIfDisabled(item.streamEntity.thumbnailUrl))
262263

263264
return MediaBrowserCompat.MediaItem(
264265
builder.build(),
@@ -277,7 +278,7 @@ class MediaBrowserImpl(
277278
.setSubtitle(item.uploaderName)
278279

279280
ImageStrategy.choosePreferredImage(item.thumbnails)?.let {
280-
builder.setIconUri(Uri.parse(it))
281+
builder.setIconUri(imageUriOrNullIfDisabled(it))
281282
}
282283

283284
return MediaBrowserCompat.MediaItem(
@@ -316,7 +317,7 @@ class MediaBrowserImpl(
316317
builder.setMediaId(mediaId)
317318
.setTitle(streamHistoryEntry.streamEntity.title)
318319
.setSubtitle(streamHistoryEntry.streamEntity.uploader)
319-
.setIconUri(Uri.parse(streamHistoryEntry.streamEntity.thumbnailUrl))
320+
.setIconUri(imageUriOrNullIfDisabled(streamHistoryEntry.streamEntity.thumbnailUrl))
320321

321322
return MediaBrowserCompat.MediaItem(
322323
builder.build(),
@@ -395,5 +396,13 @@ class MediaBrowserImpl(
395396

396397
companion object {
397398
private val TAG: String = MediaBrowserImpl::class.java.getSimpleName()
399+
400+
fun imageUriOrNullIfDisabled(url: String?): Uri? {
401+
return if (ImageStrategy.shouldLoadImages()) {
402+
url?.toUri()
403+
} else {
404+
null
405+
}
406+
}
398407
}
399408
}

app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.os.Bundle
66
import android.os.ResultReceiver
77
import android.support.v4.media.session.PlaybackStateCompat
88
import android.util.Log
9+
import androidx.core.net.toUri
910
import com.google.android.exoplayer2.Player
1011
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector.PlaybackPreparer
1112
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
@@ -137,7 +138,7 @@ class MediaBrowserPlaybackPreparer(
137138

138139
private fun extractPlayQueueFromMediaId(mediaId: String): Single<PlayQueue> {
139140
try {
140-
val mediaIdUri = Uri.parse(mediaId)
141+
val mediaIdUri = mediaId.toUri()
141142
val path = ArrayList(mediaIdUri.pathSegments)
142143
if (path.isEmpty()) {
143144
throw parseError(mediaId)

0 commit comments

Comments
 (0)