ktlint: Fix standard_argument-list-wrapping violations
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
parent
8f779d8ac5
commit
3ae93402cf
28 changed files with 306 additions and 122 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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/"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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}"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue