Skip to content

Commit 8c3e1dc

Browse files
Merge branch 'refactor' into PoToken-suspend
2 parents 010b719 + f16becc commit 8c3e1dc

199 files changed

Lines changed: 3227 additions & 2079 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/image-minimizer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ module.exports = async ({github, context}) => {
3333

3434
// Regex for finding images (simple variant) ![ALT_TEXT](https://*.githubusercontent.com/<number>/<variousHexStringsAnd->.<fileExtension>)
3535
const REGEX_USER_CONTENT_IMAGE_LOOKUP = /\!\[([^\]]*)\]\((https:\/\/[-a-z0-9]+\.githubusercontent\.com\/\d+\/[-0-9a-f]{32,512}\.(jpg|gif|png))\)/gm;
36-
const REGEX_ASSETS_IMAGE_LOCKUP = /\!\[([^\]]*)\]\((https:\/\/github\.com\/[-\w\d]+\/[-\w\d]+\/assets\/\d+\/[\-0-9a-f]{32,512})\)/gm;
36+
const REGEX_ASSETS_IMAGE_LOOKUP = /\!\[([^\]]*)\]\((https:\/\/github\.com\/(?:user-attachments\/assets|[-\w\d]+\/[-\w\d]+\/assets\/\d+)\/[\-0-9a-f]{32,512})\)/gm;
3737

3838
// Check if we found something
3939
let foundSimpleImages = REGEX_USER_CONTENT_IMAGE_LOOKUP.test(initialBody)
40-
|| REGEX_ASSETS_IMAGE_LOCKUP.test(initialBody);
40+
|| REGEX_ASSETS_IMAGE_LOOKUP.test(initialBody);
4141
if (!foundSimpleImages) {
4242
console.log('Found no simple images to process');
4343
return;
@@ -52,7 +52,7 @@ module.exports = async ({github, context}) => {
5252

5353
// Try to find and replace the images with minimized ones
5454
let newBody = await replaceAsync(initialBody, REGEX_USER_CONTENT_IMAGE_LOOKUP, minimizeAsync);
55-
newBody = await replaceAsync(newBody, REGEX_ASSETS_IMAGE_LOCKUP, minimizeAsync);
55+
newBody = await replaceAsync(newBody, REGEX_ASSETS_IMAGE_LOOKUP, minimizeAsync);
5656

5757
if (!wasMatchModified) {
5858
console.log('Nothing was modified. Skipping update');

app/build.gradle

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ plugins {
99
alias libs.plugins.kotlin.compose
1010
alias libs.plugins.kotlin.kapt
1111
alias libs.plugins.kotlin.parcelize
12+
alias libs.plugins.kotlinx.serialization
1213
alias libs.plugins.checkstyle
1314
alias libs.plugins.sonarqube
1415
alias libs.plugins.hilt
1516
alias libs.plugins.aboutlibraries
1617
}
1718

1819
android {
19-
compileSdk 34
20+
compileSdk 35
2021
namespace 'org.schabi.newpipe'
2122

2223
defaultConfig {
@@ -27,9 +28,9 @@ android {
2728
if (System.properties.containsKey('versionCodeOverride')) {
2829
versionCode System.getProperty('versionCodeOverride') as Integer
2930
} else {
30-
versionCode 1003
31+
versionCode 1004
3132
}
32-
versionName "0.27.6"
33+
versionName "0.27.7"
3334
if (System.properties.containsKey('versionNameSuffix')) {
3435
versionNameSuffix System.getProperty('versionNameSuffix')
3536
}
@@ -101,6 +102,10 @@ android {
101102
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
102103
}
103104

105+
androidResources {
106+
generateLocaleConfig = true
107+
}
108+
104109
buildFeatures {
105110
viewBinding true
106111
compose true
@@ -222,7 +227,6 @@ dependencies {
222227
implementation libs.androidx.fragment.compose
223228
implementation libs.androidx.lifecycle.livedata
224229
implementation libs.androidx.lifecycle.viewmodel
225-
implementation libs.androidx.localbroadcastmanager
226230
implementation libs.androidx.media
227231
implementation libs.androidx.preference
228232
implementation libs.androidx.recyclerview
@@ -315,6 +319,9 @@ dependencies {
315319
// Scroll
316320
implementation libs.lazycolumnscrollbar
317321

322+
// Kotlinx Serialization
323+
implementation libs.kotlinx.serialization.json
324+
318325
/** Debugging **/
319326
// Memory leak detection
320327
debugImplementation libs.leakcanary.object.watcher

app/proguard-rules.pro

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55

66
## Rules for NewPipeExtractor
77
-keep class org.schabi.newpipe.extractor.timeago.patterns.** { *; }
8+
## Rules for Rhino and Rhino Engine
9+
-keep class org.mozilla.javascript.* { *; }
810
-keep class org.mozilla.javascript.** { *; }
11+
-keep class org.mozilla.javascript.engine.** { *; }
912
-keep class org.mozilla.classfile.ClassFileWriter
1013
-dontwarn org.mozilla.javascript.JavaToJSONConverters
1114
-dontwarn org.mozilla.javascript.tools.**
15+
-keep class javax.script.** { *; }
16+
-dontwarn javax.script.**
17+
-keep class jdk.dynalink.** { *; }
18+
-dontwarn jdk.dynalink.**
1219

1320
## Rules for ExoPlayer
1421
-keep class com.google.android.exoplayer2.** { *; }
@@ -27,3 +34,18 @@
2734

2835
## For some reason NotificationModeConfigFragment wasn't kept (only referenced in a preference xml)
2936
-keep class org.schabi.newpipe.settings.notifications.** { *; }
37+
38+
## Keep Kotlinx Serialization classes
39+
-keepclassmembers class kotlinx.serialization.json.** {
40+
*** Companion;
41+
}
42+
-keepclasseswithmembers class kotlinx.serialization.json.** {
43+
kotlinx.serialization.KSerializer serializer(...);
44+
}
45+
-keep,includedescriptorclasses class org.schabi.newpipe.**$$serializer { *; }
46+
-keepclassmembers class org.schabi.newpipe.** {
47+
*** Companion;
48+
}
49+
-keepclasseswithmembers class org.schabi.newpipe.** {
50+
kotlinx.serialization.KSerializer serializer(...);
51+
}

app/src/main/AndroidManifest.xml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
1010
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
1111
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
12+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
1213
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
1314

1415
<!-- We need to be able to open links in the browser on API 30+ -->
@@ -64,6 +65,9 @@
6465
<intent-filter>
6566
<action android:name="android.intent.action.MEDIA_BUTTON" />
6667
</intent-filter>
68+
<intent-filter>
69+
<action android:name="android.media.browse.MediaBrowserService"/>
70+
</intent-filter>
6771
</service>
6872

6973
<activity
@@ -87,8 +91,10 @@
8791
android:exported="false"
8892
android:label="@string/title_activity_about" />
8993

90-
<service android:name=".local.subscription.services.SubscriptionsImportService" />
91-
<service android:name=".local.subscription.services.SubscriptionsExportService" />
94+
<service
95+
android:name="androidx.work.impl.foreground.SystemForegroundService"
96+
android:foregroundServiceType="dataSync"
97+
tools:node="merge" />
9298
<service android:name=".local.feed.service.FeedLoadService" />
9399

94100
<activity
@@ -429,5 +435,10 @@
429435
<meta-data
430436
android:name="com.samsung.android.multidisplay.keep_process_alive"
431437
android:value="true" />
438+
<!-- Android Auto -->
439+
<meta-data android:name="com.google.android.gms.car.application"
440+
android:resource="@xml/automotive_app_desc" />
441+
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
442+
android:resource="@mipmap/ic_launcher" />
432443
</application>
433444
</manifest>

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

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import android.view.MenuItem;
3939
import android.view.View;
4040
import android.view.ViewGroup;
41+
import android.webkit.WebView;
4142
import android.widget.AdapterView;
4243
import android.widget.ArrayAdapter;
4344
import android.widget.FrameLayout;
@@ -136,6 +137,19 @@ protected void onCreate(final Bundle savedInstanceState) {
136137
ThemeHelper.setDayNightMode(this);
137138
ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this));
138139

140+
// Fixes text color turning black in dark/black mode:
141+
// https://github.com/TeamNewPipe/NewPipe/issues/12016
142+
// For further reference see: https://issuetracker.google.com/issues/37124582
143+
if (DeviceUtils.supportsWebView()) {
144+
try {
145+
new WebView(this);
146+
} catch (final Throwable e) {
147+
if (DEBUG) {
148+
Log.e(TAG, "Failed to create WebView", e);
149+
}
150+
}
151+
}
152+
139153
assureCorrectAppLanguage(this);
140154
super.onCreate(savedInstanceState);
141155

@@ -172,6 +186,8 @@ protected void onCreate(final Bundle savedInstanceState) {
172186
&& ReleaseVersionUtil.INSTANCE.isReleaseApk()) {
173187
UpdateSettingsFragment.askForConsentToUpdateChecks(this);
174188
}
189+
190+
Localization.migrateAppLanguageSettingIfNecessary(getApplicationContext());
175191
}
176192

177193
@Override
@@ -578,8 +594,8 @@ public void onBackPressed() {
578594
if (player instanceof BackPressable backPressable && !backPressable.onBackPressed()) {
579595
BottomSheetBehavior.from(mainBinding.fragmentPlayerHolder)
580596
.setState(BottomSheetBehavior.STATE_COLLAPSED);
581-
return;
582597
}
598+
return;
583599
}
584600

585601
if (fragmentManager.getBackStackEntryCount() == 1) {
@@ -826,7 +842,8 @@ private void openMiniPlayerUponPlayerStarted() {
826842
@Override
827843
public void onReceive(final Context context, final Intent intent) {
828844
if (Objects.equals(intent.getAction(),
829-
VideoDetailFragment.ACTION_PLAYER_STARTED)) {
845+
VideoDetailFragment.ACTION_PLAYER_STARTED)
846+
&& PlayerHolder.getInstance().isPlayerOpen()) {
830847
openMiniPlayerIfMissing();
831848
// At this point the player is added 100%, we can unregister. Other actions
832849
// are useless since the fragment will not be removed after that.
@@ -838,6 +855,10 @@ public void onReceive(final Context context, final Intent intent) {
838855
final IntentFilter intentFilter = new IntentFilter();
839856
intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED);
840857
registerReceiver(broadcastReceiver, intentFilter);
858+
859+
// If the PlayerHolder is not bound yet, but the service is running, try to bind to it.
860+
// Once the connection is established, the ACTION_PLAYER_STARTED will be sent.
861+
PlayerHolder.getInstance().tryBindIfNeeded(this);
841862
}
842863
}
843864

app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package org.schabi.newpipe.database.history.model
33
import androidx.room.ColumnInfo
44
import androidx.room.Embedded
55
import org.schabi.newpipe.database.stream.model.StreamEntity
6+
import org.schabi.newpipe.extractor.stream.StreamInfoItem
7+
import org.schabi.newpipe.util.image.ImageStrategy
68
import java.time.OffsetDateTime
79

810
data class StreamHistoryEntry(
@@ -27,4 +29,17 @@ data class StreamHistoryEntry(
2729
return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId &&
2830
accessDate.isEqual(other.accessDate)
2931
}
32+
33+
fun toStreamInfoItem(): StreamInfoItem =
34+
StreamInfoItem(
35+
streamEntity.serviceId,
36+
streamEntity.url,
37+
streamEntity.title,
38+
streamEntity.streamType,
39+
).apply {
40+
duration = streamEntity.duration
41+
uploaderName = streamEntity.uploader
42+
uploaderUrl = streamEntity.uploaderUrl
43+
thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl)
44+
}
3045
}

app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.schabi.newpipe.database.playlist;
22

3+
import androidx.annotation.Nullable;
4+
35
import org.schabi.newpipe.database.LocalItem;
46

57
public interface PlaylistLocalItem extends LocalItem {
@@ -10,4 +12,7 @@ public interface PlaylistLocalItem extends LocalItem {
1012
long getUid();
1113

1214
void setDisplayIndex(long displayIndex);
15+
16+
@Nullable
17+
String getThumbnailUrl();
1318
}

app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistMetadataEntry.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_STREAM_ID;
1010
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_URL;
1111

12+
import androidx.annotation.Nullable;
13+
1214
public class PlaylistMetadataEntry implements PlaylistLocalItem {
1315
public static final String PLAYLIST_STREAM_COUNT = "streamCount";
1416

@@ -71,4 +73,10 @@ public long getUid() {
7173
public void setDisplayIndex(final long displayIndex) {
7274
this.displayIndex = displayIndex;
7375
}
76+
77+
@Nullable
78+
@Override
79+
public String getThumbnailUrl() {
80+
return thumbnailUrl;
81+
}
7482
}

app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public interface PlaylistRemoteDAO extends BasicDAO<PlaylistRemoteEntity> {
3434

3535
@Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE "
3636
+ REMOTE_PLAYLIST_ID + " = :playlistId")
37-
Flowable<List<PlaylistRemoteEntity>> getPlaylist(long playlistId);
37+
Flowable<PlaylistRemoteEntity> getPlaylist(long playlistId);
3838

3939
@Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE "
4040
+ REMOTE_PLAYLIST_URL + " = :url AND " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId")

app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.text.TextUtils;
44

5+
import androidx.annotation.Nullable;
56
import androidx.room.ColumnInfo;
67
import androidx.room.Entity;
78
import androidx.room.Ignore;
@@ -134,6 +135,8 @@ public void setName(final String name) {
134135
this.name = name;
135136
}
136137

138+
@Nullable
139+
@Override
137140
public String getThumbnailUrl() {
138141
return thumbnailUrl;
139142
}

0 commit comments

Comments
 (0)