ktlint: Fix standard_argument-list-wrapping violations

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta 2026-01-21 17:24:58 +08:00
parent 8f779d8ac5
commit 3ae93402cf
28 changed files with 306 additions and 122 deletions

View file

@ -10,7 +10,6 @@ ktlint_code_style = android_studio
# https://pinterest.github.io/ktlint/latest/rules/standard/#function-naming # https://pinterest.github.io/ktlint/latest/rules/standard/#function-naming
ktlint_function_naming_ignore_when_annotated_with = Composable ktlint_function_naming_ignore_when_annotated_with = Composable
ktlint_standard_argument-list-wrapping = disabled
ktlint_standard_backing-property-naming = disabled ktlint_standard_backing-property-naming = disabled
ktlint_standard_chain-method-continuation = disabled ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled ktlint_standard_class-signature = disabled

View file

@ -176,28 +176,32 @@ class DatabaseMigrationTest {
databaseInV7.run { databaseInV7.run {
insert( insert(
"search_history", SQLiteDatabase.CONFLICT_FAIL, "search_history",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("service_id", serviceId) put("service_id", serviceId)
put("search", defaultSearch1) put("search", defaultSearch1)
} }
) )
insert( insert(
"search_history", SQLiteDatabase.CONFLICT_FAIL, "search_history",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("service_id", serviceId) put("service_id", serviceId)
put("search", defaultSearch2) put("search", defaultSearch2)
} }
) )
insert( insert(
"search_history", SQLiteDatabase.CONFLICT_FAIL, "search_history",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("service_id", otherServiceId) put("service_id", otherServiceId)
put("search", defaultSearch1) put("search", defaultSearch1)
} }
) )
insert( insert(
"search_history", SQLiteDatabase.CONFLICT_FAIL, "search_history",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("service_id", otherServiceId) put("service_id", otherServiceId)
put("search", defaultSearch2) put("search", defaultSearch2)
@ -207,13 +211,17 @@ class DatabaseMigrationTest {
} }
testHelper.runMigrationsAndValidate( testHelper.runMigrationsAndValidate(
AppDatabase.DATABASE_NAME, Migrations.DB_VER_8, AppDatabase.DATABASE_NAME,
true, Migrations.MIGRATION_7_8 Migrations.DB_VER_8,
true,
Migrations.MIGRATION_7_8
) )
testHelper.runMigrationsAndValidate( testHelper.runMigrationsAndValidate(
AppDatabase.DATABASE_NAME, Migrations.DB_VER_9, AppDatabase.DATABASE_NAME,
true, Migrations.MIGRATION_8_9 Migrations.DB_VER_9,
true,
Migrations.MIGRATION_8_9
) )
val migratedDatabaseV8 = getMigratedDatabase() val migratedDatabaseV8 = getMigratedDatabase()
@ -235,7 +243,8 @@ class DatabaseMigrationTest {
val remoteUid2: Long val remoteUid2: Long
databaseInV8.run { databaseInV8.run {
localUid1 = insert( localUid1 = insert(
"playlists", SQLiteDatabase.CONFLICT_FAIL, "playlists",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("name", DEFAULT_NAME + "1") put("name", DEFAULT_NAME + "1")
put("is_thumbnail_permanent", false) put("is_thumbnail_permanent", false)
@ -243,7 +252,8 @@ class DatabaseMigrationTest {
} }
) )
localUid2 = insert( localUid2 = insert(
"playlists", SQLiteDatabase.CONFLICT_FAIL, "playlists",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("name", DEFAULT_NAME + "2") put("name", DEFAULT_NAME + "2")
put("is_thumbnail_permanent", false) put("is_thumbnail_permanent", false)
@ -251,25 +261,29 @@ class DatabaseMigrationTest {
} }
) )
delete( delete(
"playlists", "uid = ?", "playlists",
"uid = ?",
Array(1) { localUid1 } Array(1) { localUid1 }
) )
remoteUid1 = insert( remoteUid1 = insert(
"remote_playlists", SQLiteDatabase.CONFLICT_FAIL, "remote_playlists",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("service_id", DEFAULT_SERVICE_ID) put("service_id", DEFAULT_SERVICE_ID)
put("url", DEFAULT_URL) put("url", DEFAULT_URL)
} }
) )
remoteUid2 = insert( remoteUid2 = insert(
"remote_playlists", SQLiteDatabase.CONFLICT_FAIL, "remote_playlists",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply { ContentValues().apply {
put("service_id", DEFAULT_SECOND_SERVICE_ID) put("service_id", DEFAULT_SECOND_SERVICE_ID)
put("url", DEFAULT_SECOND_URL) put("url", DEFAULT_SECOND_URL)
} }
) )
delete( delete(
"remote_playlists", "uid = ?", "remote_playlists",
"uid = ?",
Array(1) { remoteUid2 } Array(1) { remoteUid2 }
) )
close() close()

View file

@ -40,14 +40,21 @@ class FeedDAOTest {
private val stream7 = StreamEntity(7, serviceId, "https://youtube.com/watch?v=7", "stream 7", StreamType.VIDEO_STREAM, 1000, "channel-4", "https://youtube.com/channel/4", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-10", OffsetDateTime.parse("2023-08-10T00:00:00Z")) private val stream7 = StreamEntity(7, serviceId, "https://youtube.com/watch?v=7", "stream 7", StreamType.VIDEO_STREAM, 1000, "channel-4", "https://youtube.com/channel/4", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-10", OffsetDateTime.parse("2023-08-10T00:00:00Z"))
private val allStreams = listOf( private val allStreams = listOf(
stream1, stream2, stream3, stream4, stream5, stream6, stream7 stream1,
stream2,
stream3,
stream4,
stream5,
stream6,
stream7
) )
@Before @Before
fun createDb() { fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>() val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder( db = Room.inMemoryDatabaseBuilder(
context, AppDatabase::class.java context,
AppDatabase::class.java
).build() ).build()
feedDAO = db.feedDAO() feedDAO = db.feedDAO()
streamDAO = db.streamDAO() streamDAO = db.streamDAO()
@ -64,7 +71,10 @@ class FeedDAOTest {
fun testUnlinkStreamsOlderThan_KeepOne() { fun testUnlinkStreamsOlderThan_KeepOne() {
setupUnlinkDelete("2023-08-15T00:00:00Z") setupUnlinkDelete("2023-08-15T00:00:00Z")
val streams = feedDAO.getStreams( val streams = feedDAO.getStreams(
FeedGroupEntity.GROUP_ALL_ID, includePlayed = true, includePartiallyPlayed = true, null FeedGroupEntity.GROUP_ALL_ID,
includePlayed = true,
includePartiallyPlayed = true,
null
) )
.blockingGet() .blockingGet()
val allowedStreams = listOf(stream3, stream5, stream6, stream7) val allowedStreams = listOf(stream3, stream5, stream6, stream7)
@ -75,7 +85,10 @@ class FeedDAOTest {
fun testUnlinkStreamsOlderThan_KeepMultiple() { fun testUnlinkStreamsOlderThan_KeepMultiple() {
setupUnlinkDelete("2023-08-01T00:00:00Z") setupUnlinkDelete("2023-08-01T00:00:00Z")
val streams = feedDAO.getStreams( val streams = feedDAO.getStreams(
FeedGroupEntity.GROUP_ALL_ID, includePlayed = true, includePartiallyPlayed = true, null FeedGroupEntity.GROUP_ALL_ID,
includePlayed = true,
includePartiallyPlayed = true,
null
) )
.blockingGet() .blockingGet()
val allowedStreams = listOf(stream3, stream4, stream5, stream6, stream7) val allowedStreams = listOf(stream3, stream4, stream5, stream6, stream7)

View file

@ -33,8 +33,12 @@ class LocalPlaylistManagerTest {
fun createPlaylist() { fun createPlaylist() {
val NEWPIPE_URL = "https://newpipe.net/" val NEWPIPE_URL = "https://newpipe.net/"
val stream = StreamEntity( val stream = StreamEntity(
serviceId = 1, url = NEWPIPE_URL, title = "title", serviceId = 1,
streamType = StreamType.VIDEO_STREAM, duration = 1, uploader = "uploader", url = NEWPIPE_URL,
title = "title",
streamType = StreamType.VIDEO_STREAM,
duration = 1,
uploader = "uploader",
uploaderUrl = NEWPIPE_URL uploaderUrl = NEWPIPE_URL
) )
@ -58,14 +62,22 @@ class LocalPlaylistManagerTest {
@Test() @Test()
fun createPlaylist_nonExistentStreamsAreUpserted() { fun createPlaylist_nonExistentStreamsAreUpserted() {
val stream = StreamEntity( val stream = StreamEntity(
serviceId = 1, url = "https://newpipe.net/", title = "title", serviceId = 1,
streamType = StreamType.VIDEO_STREAM, duration = 1, uploader = "uploader", url = "https://newpipe.net/",
title = "title",
streamType = StreamType.VIDEO_STREAM,
duration = 1,
uploader = "uploader",
uploaderUrl = "https://newpipe.net/" uploaderUrl = "https://newpipe.net/"
) )
database.streamDAO().insert(stream) database.streamDAO().insert(stream)
val upserted = StreamEntity( val upserted = StreamEntity(
serviceId = 1, url = "https://newpipe.net/2", title = "title2", serviceId = 1,
streamType = StreamType.VIDEO_STREAM, duration = 1, uploader = "uploader", url = "https://newpipe.net/2",
title = "title2",
streamType = StreamType.VIDEO_STREAM,
duration = 1,
uploader = "uploader",
uploaderUrl = "https://newpipe.net/" uploaderUrl = "https://newpipe.net/"
) )

View file

@ -156,41 +156,51 @@ class StreamItemAdapterTest {
helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0) helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0)
helper.assertInvalidResponse( helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.png\""))), 1 getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.png\""))),
1
) )
helper.assertInvalidResponse( helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"data.csv\""))), 2 getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"data.csv\""))),
2
) )
helper.assertInvalidResponse( helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; filename=\"data.csv\""))), 3 getResponse(mapOf(Pair("Content-Disposition", "form-data; filename=\"data.csv\""))),
3
) )
helper.assertInvalidResponse( helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"fieldName\"; filename*=\"filename.jpg\""))), 4 getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"fieldName\"; filename*=\"filename.jpg\""))),
4
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.ogg\""))), getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.ogg\""))),
5, MediaFormat.OGG 5,
MediaFormat.OGG
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "some-form-data; filename=\"audio.flac\""))), getResponse(mapOf(Pair("Content-Disposition", "some-form-data; filename=\"audio.flac\""))),
6, MediaFormat.FLAC 6,
MediaFormat.FLAC
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.aiff\"; filename=\"audio.aiff\""))), getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.aiff\"; filename=\"audio.aiff\""))),
7, MediaFormat.AIFF 7,
MediaFormat.AIFF
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"alien?\"; filename*=UTF-8''%CE%B1%CE%BB%CE%B9%CF%B5%CE%BD.m4a"))), getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"alien?\"; filename*=UTF-8''%CE%B1%CE%BB%CE%B9%CF%B5%CE%BD.m4a"))),
8, MediaFormat.M4A 8,
MediaFormat.M4A
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=UTF-8''alien.opus"))), getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=UTF-8''alien.opus"))),
9, MediaFormat.OPUS 9,
MediaFormat.OPUS
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=\"UTF-8''alien.opus\""))), getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=\"UTF-8''alien.opus\""))),
10, MediaFormat.OPUS 10,
MediaFormat.OPUS
) )
} }
@ -213,16 +223,24 @@ class StreamItemAdapterTest {
helper.assertInvalidResponse(getResponse(mapOf()), 7) helper.assertInvalidResponse(getResponse(mapOf()), 7)
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/flac"))), 8, MediaFormat.FLAC getResponse(mapOf(Pair("Content-Type", "audio/flac"))),
8,
MediaFormat.FLAC
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/wav"))), 9, MediaFormat.WAV getResponse(mapOf(Pair("Content-Type", "audio/wav"))),
9,
MediaFormat.WAV
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/opus"))), 10, MediaFormat.OPUS getResponse(mapOf(Pair("Content-Type", "audio/opus"))),
10,
MediaFormat.OPUS
) )
helper.assertValidResponse( helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/aiff"))), 11, MediaFormat.AIFF getResponse(mapOf(Pair("Content-Type", "audio/aiff"))),
11,
MediaFormat.AIFF
) )
} }
@ -345,7 +363,8 @@ class StreamItemAdapterTest {
index: Int index: Int
) { ) {
assertFalse( assertFalse(
"invalid header returns valid value", retrieveMediaFormat(streams[index], response) "invalid header returns valid value",
retrieveMediaFormat(streams[index], response)
) )
assertNull("Media format extracted although stated otherwise", wrapper.getFormat(index)) assertNull("Media format extracted although stated otherwise", wrapper.getFormat(index))
} }
@ -359,7 +378,8 @@ class StreamItemAdapterTest {
format: MediaFormat format: MediaFormat
) { ) {
assertTrue( assertTrue(
"header was not recognized", retrieveMediaFormat(streams[index], response) "header was not recognized",
retrieveMediaFormat(streams[index], response)
) )
assertEquals("Wrong media format extracted", format, wrapper.getFormat(index)) assertEquals("Wrong media format extracted", format, wrapper.getFormat(index))
} }

View file

@ -46,7 +46,8 @@ class NewVersionWorker(
// Show toast stating that the app is up-to-date if the update check was manual. // Show toast stating that the app is up-to-date if the update check was manual.
ContextCompat.getMainExecutor(applicationContext).execute { ContextCompat.getMainExecutor(applicationContext).execute {
Toast.makeText( Toast.makeText(
applicationContext, R.string.app_update_unavailable_toast, applicationContext,
R.string.app_update_unavailable_toast,
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
@ -58,7 +59,11 @@ class NewVersionWorker(
val intent = Intent(Intent.ACTION_VIEW, apkLocationUrl?.toUri()) val intent = Intent(Intent.ACTION_VIEW, apkLocationUrl?.toUri())
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val pendingIntent = PendingIntentCompat.getActivity( val pendingIntent = PendingIntentCompat.getActivity(
applicationContext, 0, intent, 0, false applicationContext,
0,
intent,
0,
false
) )
val channelId = applicationContext.getString(R.string.app_update_notification_channel_id) val channelId = applicationContext.getString(R.string.app_update_notification_channel_id)
val notificationBuilder = NotificationCompat.Builder(applicationContext, channelId) val notificationBuilder = NotificationCompat.Builder(applicationContext, channelId)
@ -71,7 +76,8 @@ class NewVersionWorker(
) )
.setContentText( .setContentText(
applicationContext.getString( applicationContext.getString(
R.string.app_update_available_notification_text, versionName R.string.app_update_available_notification_text,
versionName
) )
) )

View file

@ -116,85 +116,144 @@ class AboutActivity : AppCompatActivity() {
*/ */
private val SOFTWARE_COMPONENTS = arrayListOf( private val SOFTWARE_COMPONENTS = arrayListOf(
SoftwareComponent( SoftwareComponent(
"ACRA", "2013", "Kevin Gaudin", "ACRA",
"https://github.com/ACRA/acra", StandardLicenses.APACHE2 "2013",
"Kevin Gaudin",
"https://github.com/ACRA/acra",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"AndroidX", "2005 - 2011", "The Android Open Source Project", "AndroidX",
"https://developer.android.com/jetpack", StandardLicenses.APACHE2 "2005 - 2011",
"The Android Open Source Project",
"https://developer.android.com/jetpack",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"ExoPlayer", "2014 - 2020", "Google, Inc.", "ExoPlayer",
"https://github.com/google/ExoPlayer", StandardLicenses.APACHE2 "2014 - 2020",
"Google, Inc.",
"https://github.com/google/ExoPlayer",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"GigaGet", "2014 - 2015", "Peter Cai", "GigaGet",
"https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL3 "2014 - 2015",
"Peter Cai",
"https://github.com/PaperAirplane-Dev-Team/GigaGet",
StandardLicenses.GPL3
), ),
SoftwareComponent( SoftwareComponent(
"Groupie", "2016", "Lisa Wray", "Groupie",
"https://github.com/lisawray/groupie", StandardLicenses.MIT "2016",
"Lisa Wray",
"https://github.com/lisawray/groupie",
StandardLicenses.MIT
), ),
SoftwareComponent( SoftwareComponent(
"Android-State", "2018", "Evernote", "Android-State",
"https://github.com/Evernote/android-state", StandardLicenses.EPL1 "2018",
"Evernote",
"https://github.com/Evernote/android-state",
StandardLicenses.EPL1
), ),
SoftwareComponent( SoftwareComponent(
"Bridge", "2021", "Livefront", "Bridge",
"https://github.com/livefront/bridge", StandardLicenses.APACHE2 "2021",
"Livefront",
"https://github.com/livefront/bridge",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"Jsoup", "2009 - 2020", "Jonathan Hedley", "Jsoup",
"https://github.com/jhy/jsoup", StandardLicenses.MIT "2009 - 2020",
"Jonathan Hedley",
"https://github.com/jhy/jsoup",
StandardLicenses.MIT
), ),
SoftwareComponent( SoftwareComponent(
"Markwon", "2019", "Dimitry Ivanov", "Markwon",
"https://github.com/noties/Markwon", StandardLicenses.APACHE2 "2019",
"Dimitry Ivanov",
"https://github.com/noties/Markwon",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"Material Components for Android", "2016 - 2020", "Google, Inc.", "Material Components for Android",
"2016 - 2020",
"Google, Inc.",
"https://github.com/material-components/material-components-android", "https://github.com/material-components/material-components-android",
StandardLicenses.APACHE2 StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"NewPipe Extractor", "2017 - 2020", "Christian Schabesberger", "NewPipe Extractor",
"https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3 "2017 - 2020",
"Christian Schabesberger",
"https://github.com/TeamNewPipe/NewPipeExtractor",
StandardLicenses.GPL3
), ),
SoftwareComponent( SoftwareComponent(
"NoNonsense-FilePicker", "2016", "Jonas Kalderstam", "NoNonsense-FilePicker",
"https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2 "2016",
"Jonas Kalderstam",
"https://github.com/spacecowboy/NoNonsense-FilePicker",
StandardLicenses.MPL2
), ),
SoftwareComponent( SoftwareComponent(
"OkHttp", "2019", "Square, Inc.", "OkHttp",
"https://square.github.io/okhttp/", StandardLicenses.APACHE2 "2019",
"Square, Inc.",
"https://square.github.io/okhttp/",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"Picasso", "2013", "Square, Inc.", "Picasso",
"https://square.github.io/picasso/", StandardLicenses.APACHE2 "2013",
"Square, Inc.",
"https://square.github.io/picasso/",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"PrettyTime", "2012 - 2020", "Lincoln Baxter, III", "PrettyTime",
"https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2 "2012 - 2020",
"Lincoln Baxter, III",
"https://github.com/ocpsoft/prettytime",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"ProcessPhoenix", "2015", "Jake Wharton", "ProcessPhoenix",
"https://github.com/JakeWharton/ProcessPhoenix", StandardLicenses.APACHE2 "2015",
"Jake Wharton",
"https://github.com/JakeWharton/ProcessPhoenix",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"RxAndroid", "2015", "The RxAndroid authors", "RxAndroid",
"https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2 "2015",
"The RxAndroid authors",
"https://github.com/ReactiveX/RxAndroid",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"RxBinding", "2015", "Jake Wharton", "RxBinding",
"https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2 "2015",
"Jake Wharton",
"https://github.com/JakeWharton/RxBinding",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"RxJava", "2016 - 2020", "RxJava Contributors", "RxJava",
"https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2 "2016 - 2020",
"RxJava Contributors",
"https://github.com/ReactiveX/RxJava",
StandardLicenses.APACHE2
), ),
SoftwareComponent( SoftwareComponent(
"SearchPreference", "2018", "ByteHamster", "SearchPreference",
"https://github.com/ByteHamster/SearchPreference", StandardLicenses.MIT "2018",
"ByteHamster",
"https://github.com/ByteHamster/SearchPreference",
StandardLicenses.MIT
) )
) )
} }

View file

@ -97,7 +97,8 @@ class LicenseFragment : Fragment() {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe { formattedLicense -> .subscribe { formattedLicense ->
val webViewData = Base64.encodeToString( val webViewData = Base64.encodeToString(
formattedLicense.toByteArray(), Base64.NO_PADDING formattedLicense.toByteArray(),
Base64.NO_PADDING
) )
val webView = WebView(context) val webView = WebView(context)
webView.loadData(webViewData, "text/html; charset=UTF-8", "base64") webView.loadData(webViewData, "text/html; charset=UTF-8", "base64")

View file

@ -28,13 +28,16 @@ fun getFormattedLicense(context: Context, license: License): String {
fun getLicenseStylesheet(context: Context): String { fun getLicenseStylesheet(context: Context): String {
val isLightTheme = ThemeHelper.isLightThemeSelected(context) val isLightTheme = ThemeHelper.isLightThemeSelected(context)
val licenseBackgroundColor = getHexRGBColor( val licenseBackgroundColor = getHexRGBColor(
context, if (isLightTheme) R.color.light_license_background_color else R.color.dark_license_background_color context,
if (isLightTheme) R.color.light_license_background_color else R.color.dark_license_background_color
) )
val licenseTextColor = getHexRGBColor( val licenseTextColor = getHexRGBColor(
context, if (isLightTheme) R.color.light_license_text_color else R.color.dark_license_text_color context,
if (isLightTheme) R.color.light_license_text_color else R.color.dark_license_text_color
) )
val youtubePrimaryColor = getHexRGBColor( val youtubePrimaryColor = getHexRGBColor(
context, if (isLightTheme) R.color.light_youtube_primary_color else R.color.dark_youtube_primary_color context,
if (isLightTheme) R.color.light_youtube_primary_color else R.color.dark_youtube_primary_color
) )
return "body{padding:12px 15px;margin:0;background:#$licenseBackgroundColor;color:#$licenseTextColor}" + return "body{padding:12px 15px;margin:0;background:#$licenseBackgroundColor;color:#$licenseTextColor}" +
"a[href]{color:#$youtubePrimaryColor}pre{white-space:pre-wrap}" "a[href]{color:#$youtubePrimaryColor}pre{white-space:pre-wrap}"

View file

@ -19,13 +19,17 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
entity = StreamEntity::class, entity = StreamEntity::class,
parentColumns = [StreamEntity.STREAM_ID], parentColumns = [StreamEntity.STREAM_ID],
childColumns = [STREAM_ID], childColumns = [STREAM_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE,
deferred = true
), ),
ForeignKey( ForeignKey(
entity = SubscriptionEntity::class, entity = SubscriptionEntity::class,
parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID],
childColumns = [SUBSCRIPTION_ID], childColumns = [SUBSCRIPTION_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE,
deferred = true
) )
] ]
) )

View file

@ -18,14 +18,18 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
entity = FeedGroupEntity::class, entity = FeedGroupEntity::class,
parentColumns = [FeedGroupEntity.ID], parentColumns = [FeedGroupEntity.ID],
childColumns = [GROUP_ID], childColumns = [GROUP_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE,
deferred = true
), ),
ForeignKey( ForeignKey(
entity = SubscriptionEntity::class, entity = SubscriptionEntity::class,
parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID],
childColumns = [SUBSCRIPTION_ID], childColumns = [SUBSCRIPTION_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE,
deferred = true
) )
] ]
) )

View file

@ -16,7 +16,9 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
entity = SubscriptionEntity::class, entity = SubscriptionEntity::class,
parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID],
childColumns = [SUBSCRIPTION_ID], childColumns = [SUBSCRIPTION_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE,
deferred = true
) )
] ]
) )

View file

@ -86,8 +86,12 @@ data class StreamEntity(
@Ignore @Ignore
constructor(item: PlayQueueItem) : this( constructor(item: PlayQueueItem) : this(
serviceId = item.serviceId, url = item.url, title = item.title, serviceId = item.serviceId,
streamType = item.streamType, duration = item.duration, uploader = item.uploader, url = item.url,
title = item.title,
streamType = item.streamType,
duration = item.duration,
uploader = item.uploader,
uploaderUrl = item.uploaderUrl, uploaderUrl = item.uploaderUrl,
thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails) thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails)
) )

View file

@ -43,8 +43,14 @@ fun View.animate(
if (DEBUG) { if (DEBUG) {
val id = runCatching { resources.getResourceEntryName(id) }.getOrDefault(id.toString()) val id = runCatching { resources.getResourceEntryName(id) }.getOrDefault(id.toString())
val msg = String.format( val msg = String.format(
"%8s → [%s:%s] [%s %s:%s] execOnEnd=%s", enterOrExit, "%8s → [%s:%s] [%s %s:%s] execOnEnd=%s",
javaClass.simpleName, id, animationType, duration, delay, execOnEnd enterOrExit,
javaClass.simpleName,
id,
animationType,
duration,
delay,
execOnEnd
) )
Log.d(TAG, "animate(): $msg") Log.d(TAG, "animate(): $msg")
} }

View file

@ -390,8 +390,13 @@ class FeedFragment : BaseStateFragment<FeedState>() {
if (item is StreamItem && !isRefreshing) { if (item is StreamItem && !isRefreshing) {
val stream = item.streamWithState.stream val stream = item.streamWithState.stream
NavigationHelper.openVideoDetailFragment( NavigationHelper.openVideoDetailFragment(
requireContext(), fm, requireContext(),
stream.serviceId, stream.url, stream.title, null, false fm,
stream.serviceId,
stream.url,
stream.title,
null,
false
) )
} }
} }
@ -503,7 +508,8 @@ class FeedFragment : BaseStateFragment<FeedState>() {
) { ) {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val isFastFeedModeEnabled = sharedPreferences.getBoolean( val isFastFeedModeEnabled = sharedPreferences.getBoolean(
getString(R.string.feed_use_dedicated_fetch_method_key), false getString(R.string.feed_use_dedicated_fetch_method_key),
false
) )
val builder = AlertDialog.Builder(requireContext()) val builder = AlertDialog.Builder(requireContext())
@ -538,7 +544,8 @@ class FeedFragment : BaseStateFragment<FeedState>() {
private fun updateRelativeTimeViews() { private fun updateRelativeTimeViews() {
updateRefreshViewState() updateRefreshViewState()
groupAdapter.notifyItemRangeChanged( groupAdapter.notifyItemRangeChanged(
0, groupAdapter.itemCount, 0,
groupAdapter.itemCount,
StreamItem.UPDATE_RELATIVE_TIME StreamItem.UPDATE_RELATIVE_TIME
) )
} }

View file

@ -42,7 +42,9 @@ class NotificationHelper(val context: Context) {
fun displayNewStreamsNotifications(data: FeedUpdateInfo) { fun displayNewStreamsNotifications(data: FeedUpdateInfo) {
val newStreams = data.newStreams val newStreams = data.newStreams
val summary = context.resources.getQuantityString( val summary = context.resources.getQuantityString(
R.plurals.new_streams, newStreams.size, newStreams.size R.plurals.new_streams,
newStreams.size,
newStreams.size
) )
val summaryBuilder = NotificationCompat.Builder( val summaryBuilder = NotificationCompat.Builder(
context, context,

View file

@ -87,7 +87,8 @@ class FeedLoadManager(private val context: Context) {
) )
GROUP_NOTIFICATION_ENABLED -> feedDatabaseManager.outdatedSubscriptionsWithNotificationMode( GROUP_NOTIFICATION_ENABLED -> feedDatabaseManager.outdatedSubscriptionsWithNotificationMode(
outdatedThreshold, NotificationMode.ENABLED outdatedThreshold,
NotificationMode.ENABLED
) )
else -> feedDatabaseManager.outdatedSubscriptionsForGroup(groupId, outdatedThreshold) else -> feedDatabaseManager.outdatedSubscriptionsForGroup(groupId, outdatedThreshold)
@ -188,7 +189,8 @@ class FeedLoadManager(private val context: Context) {
val channelInfo = getChannelInfo( val channelInfo = getChannelInfo(
subscriptionEntity.serviceId, subscriptionEntity.serviceId,
subscriptionEntity.url, true subscriptionEntity.url,
true
) )
.onErrorReturn(storeOriginalErrorAndRethrow) .onErrorReturn(storeOriginalErrorAndRethrow)
.blockingGet() .blockingGet()
@ -218,7 +220,8 @@ class FeedLoadManager(private val context: Context) {
) { ) {
val infoItemsPage = getMoreChannelTabItems( val infoItemsPage = getMoreChannelTabItems(
subscriptionEntity.serviceId, subscriptionEntity.serviceId,
linkHandler, channelTabInfo.nextPage linkHandler,
channelTabInfo.nextPage
) )
.blockingGet() .blockingGet()

View file

@ -346,7 +346,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
val actions = DialogInterface.OnClickListener { _, i -> val actions = DialogInterface.OnClickListener { _, i ->
when (i) { when (i) {
0 -> ShareUtils.shareText( 0 -> ShareUtils.shareText(
requireContext(), selectedItem.name, selectedItem.url, selectedItem.thumbnails requireContext(),
selectedItem.name,
selectedItem.url,
selectedItem.thumbnails
) )
1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url)
@ -380,7 +383,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private val listenerChannelItem = object : OnClickGesture<ChannelInfoItem> { private val listenerChannelItem = object : OnClickGesture<ChannelInfoItem> {
override fun selected(selectedItem: ChannelInfoItem) = NavigationHelper.openChannelFragment( override fun selected(selectedItem: ChannelInfoItem) = NavigationHelper.openChannelFragment(
fm, fm,
selectedItem.serviceId, selectedItem.url, selectedItem.name selectedItem.serviceId,
selectedItem.url,
selectedItem.name
) )
override fun held(selectedItem: ChannelInfoItem) = showLongTapDialog(selectedItem) override fun held(selectedItem: ChannelInfoItem) = showLongTapDialog(selectedItem)

View file

@ -37,7 +37,8 @@ class SubscriptionManager(context: Context) {
filterQuery.isNotEmpty() -> { filterQuery.isNotEmpty() -> {
return if (showOnlyUngrouped) { return if (showOnlyUngrouped) {
subscriptionTable.getSubscriptionsOnlyUngroupedFiltered( subscriptionTable.getSubscriptionsOnlyUngroupedFiltered(
currentGroupId, filterQuery currentGroupId,
filterQuery
) )
} else { } else {
subscriptionTable.getSubscriptionsFiltered(filterQuery) subscriptionTable.getSubscriptionsFiltered(filterQuery)

View file

@ -178,8 +178,10 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
itemAnimator = null itemAnimator = null
adapter = subscriptionGroupAdapter adapter = subscriptionGroupAdapter
layoutManager = GridLayoutManager( layoutManager = GridLayoutManager(
requireContext(), subscriptionGroupAdapter.spanCount, requireContext(),
RecyclerView.VERTICAL, false subscriptionGroupAdapter.spanCount,
RecyclerView.VERTICAL,
false
).apply { ).apply {
spanSizeLookup = subscriptionGroupAdapter.spanSizeLookup spanSizeLookup = subscriptionGroupAdapter.spanSizeLookup
} }
@ -387,7 +389,8 @@ class FeedGroupDialog : DialogFragment(), BackPressable {
val selectedCount = this.selectedSubscriptions.size val selectedCount = this.selectedSubscriptions.size
val selectedCountText = resources.getQuantityString( val selectedCountText = resources.getQuantityString(
R.plurals.feed_group_dialog_selection_count, R.plurals.feed_group_dialog_selection_count,
selectedCount, selectedCount selectedCount,
selectedCount
) )
feedGroupCreateBinding.selectedSubscriptionCountView.text = selectedCountText feedGroupCreateBinding.selectedSubscriptionCountView.text = selectedCountText
feedGroupCreateBinding.subscriptionsHeaderInfo.text = selectedCountText feedGroupCreateBinding.subscriptionsHeaderInfo.text = selectedCountText

View file

@ -55,7 +55,8 @@ class FeedGroupDialogViewModel(
private var subscriptionsDisposable = Flowable private var subscriptionsDisposable = Flowable
.combineLatest( .combineLatest(
subscriptionsFlowable, feedDatabaseManager.subscriptionIdsForGroup(groupId) subscriptionsFlowable,
feedDatabaseManager.subscriptionIdsForGroup(groupId)
) { t1: List<PickerSubscriptionItem>, t2: List<Long> -> t1 to t2.toSet() } ) { t1: List<PickerSubscriptionItem>, t2: List<Long> -> t1 to t2.toSet() }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.subscribe(mutableSubscriptionsLiveData::postValue) .subscribe(mutableSubscriptionsLiveData::postValue)
@ -125,7 +126,10 @@ class FeedGroupDialogViewModel(
) = viewModelFactory { ) = viewModelFactory {
initializer { initializer {
FeedGroupDialogViewModel( FeedGroupDialogViewModel(
context.applicationContext, groupId, initialQuery, initialShowOnlyUngrouped context.applicationContext,
groupId,
initialQuery,
initialShowOnlyUngrouped
) )
} }
} }

View file

@ -90,7 +90,8 @@ class MediaBrowserImpl(
val extras = Bundle() val extras = Bundle()
extras.putBoolean( extras.putBoolean(
MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED,
true
) )
return MediaBrowserServiceCompat.BrowserRoot(ID_ROOT, extras) return MediaBrowserServiceCompat.BrowserRoot(ID_ROOT, extras)
} }

View file

@ -31,10 +31,12 @@ object FilenameUtils {
val defaultCharset = context.getString(R.string.default_file_charset_value) val defaultCharset = context.getString(R.string.default_file_charset_value)
val replacementChar = sharedPreferences.getStringSafe( val replacementChar = sharedPreferences.getStringSafe(
context.getString(R.string.settings_file_replacement_character_key), "_" context.getString(R.string.settings_file_replacement_character_key),
"_"
) )
val selectedCharset = sharedPreferences.getStringSafe( val selectedCharset = sharedPreferences.getStringSafe(
context.getString(R.string.settings_file_charset_key), "" context.getString(R.string.settings_file_charset_key),
""
).ifEmpty { defaultCharset } ).ifEmpty { defaultCharset }
val charset = when (selectedCharset) { val charset = when (selectedCharset) {

View file

@ -26,7 +26,8 @@ object ReleaseVersionUtil {
PackageInfoCompat.hasSignatures(app.packageManager, app.packageName, certificates, false) PackageInfoCompat.hasSignatures(app.packageManager, app.packageName, certificates, false)
} catch (e: PackageManager.NameNotFoundException) { } catch (e: PackageManager.NameNotFoundException) {
createNotification( createNotification(
app, ErrorInfo(e, UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not find package info") app,
ErrorInfo(e, UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not find package info")
) )
false false
} }

View file

@ -115,8 +115,10 @@ class PlayerFastSeekOverlay(context: Context, attrs: AttributeSet?) :
clone(rootConstraintLayout) clone(rootConstraintLayout)
clear(secondsView.id, if (forward) START else END) clear(secondsView.id, if (forward) START else END)
connect( connect(
secondsView.id, if (forward) END else START, secondsView.id,
PARENT_ID, if (forward) END else START if (forward) END else START,
PARENT_ID,
if (forward) END else START
) )
secondsView.startAnimation() secondsView.startAnimation()
applyTo(rootConstraintLayout) applyTo(rootConstraintLayout)

View file

@ -29,7 +29,9 @@ class SecondsView(context: Context, attrs: AttributeSet?) : LinearLayout(context
var seconds: Int = 0 var seconds: Int = 0
set(value) { set(value) {
binding.tvSeconds.text = context.resources.getQuantityString( binding.tvSeconds.text = context.resources.getQuantityString(
R.plurals.seconds, value, value R.plurals.seconds,
value,
value
) )
field = value field = value
} }

View file

@ -15,7 +15,8 @@ class FeedGroupIconTest {
assertEquals( assertEquals(
"Gap between ids detected (current item: ${currentIcon.name} - ${currentIcon.id} → should be: $shouldBeId)", "Gap between ids detected (current item: ${currentIcon.name} - ${currentIcon.id} → should be: $shouldBeId)",
shouldBeId, currentIcon.id shouldBeId,
currentIcon.id
) )
} }
} }

View file

@ -161,8 +161,11 @@ class ImportAllCombinationsTest {
} catch (e: Throwable) { } catch (e: Throwable) {
failedAssertions.add( failedAssertions.add(
FailData( FailData(
containsDb, containsSer, containsJson, containsDb,
filename, e containsSer,
containsJson,
filename,
e
) )
) )
} }