mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-13 13:50:30 +05:30
Merge pull request #3585 from Isira-Seneviratne/AGP_8.0
Upgrade to AGP 8.0.
This commit is contained in:
commit
9dcdda2bab
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -33,10 +33,10 @@ jobs:
|
||||
python checkrun.py
|
||||
cd ..
|
||||
|
||||
- name: Set up JDK 11
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 11
|
||||
java-version: 17
|
||||
distribution: "temurin"
|
||||
cache: "gradle"
|
||||
|
||||
|
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@ -37,9 +37,17 @@ jobs:
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
|
||||
steps:
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Java 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: "temurin"
|
||||
cache: "gradle"
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
|
@ -53,11 +53,11 @@ android {
|
||||
}
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
jvmTarget = JavaVersion.VERSION_17
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
|
54
app/proguard-rules.pro
vendored
54
app/proguard-rules.pro
vendored
@ -52,3 +52,57 @@
|
||||
}
|
||||
|
||||
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
|
||||
|
||||
# -- Retrofit keep rules, obtained from https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro
|
||||
|
||||
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
|
||||
# EnclosingMethod is required to use InnerClasses.
|
||||
-keepattributes Signature, InnerClasses, EnclosingMethod
|
||||
|
||||
# Retrofit does reflection on method and parameter annotations.
|
||||
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
|
||||
|
||||
# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
|
||||
-keepattributes AnnotationDefault
|
||||
|
||||
# Retain service method parameters when optimizing.
|
||||
-keepclassmembers,allowshrinking,allowobfuscation interface * {
|
||||
@retrofit2.http.* <methods>;
|
||||
}
|
||||
|
||||
# Ignore annotation used for build tooling.
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
|
||||
# Ignore JSR 305 annotations for embedding nullability information.
|
||||
-dontwarn javax.annotation.**
|
||||
|
||||
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
|
||||
-dontwarn kotlin.Unit
|
||||
|
||||
# Top-level functions that can only be used by Kotlin.
|
||||
-dontwarn retrofit2.KotlinExtensions
|
||||
-dontwarn retrofit2.KotlinExtensions$*
|
||||
|
||||
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
|
||||
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
|
||||
-if interface * { @retrofit2.http.* <methods>; }
|
||||
-keep,allowobfuscation interface <1>
|
||||
|
||||
# Keep inherited services.
|
||||
-if interface * { @retrofit2.http.* <methods>; }
|
||||
-keep,allowobfuscation interface * extends <1>
|
||||
|
||||
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
|
||||
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
|
||||
-keep,allowobfuscation,allowshrinking class retrofit2.Response
|
||||
|
||||
# With R8 full mode generic signatures are stripped for classes that are not
|
||||
# kept. Suspend functions are wrapped in continuations where the type argument
|
||||
# is used.
|
||||
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
|
||||
|
||||
# -- End of Retrofit keep rules
|
||||
|
||||
-dontwarn org.conscrypt.**
|
||||
-dontwarn org.bouncycastle.**
|
||||
-dontwarn org.openjsse.**
|
||||
|
@ -35,7 +35,6 @@ data class Streams(
|
||||
val uploaderSubscriberCount: Long = 0,
|
||||
val previewFrames: List<PreviewFrames> = emptyList(),
|
||||
) {
|
||||
@Suppress("NewApi") // The Paths class is desugared.
|
||||
fun toDownloadItems(
|
||||
videoId: String,
|
||||
fileName: String,
|
||||
|
@ -10,6 +10,5 @@ fun Path.toAndroidUriOrNull(): Uri? {
|
||||
}
|
||||
|
||||
fun Path.toAndroidUri(): Uri {
|
||||
@Suppress("NewApi") // The Path class is desugared.
|
||||
return toFile().toUri()
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.db.obj.DownloadItem
|
||||
import com.github.libretube.services.DownloadService
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createDirectories
|
||||
|
||||
object DownloadHelper {
|
||||
const val VIDEO_DIR = "video"
|
||||
@ -35,8 +34,11 @@ object DownloadHelper {
|
||||
}
|
||||
|
||||
fun getDownloadDir(context: Context, path: String): Path {
|
||||
@Suppress("NewApi") // The Path class is desugared.
|
||||
return getOfflineStorageDir(context).resolve(path).createDirectories()
|
||||
// TODO: Use createDirectories() when https://issuetracker.google.com/issues/279034662 is
|
||||
// fixed.
|
||||
return getOfflineStorageDir(context).resolve(path).apply {
|
||||
toFile().mkdirs()
|
||||
}
|
||||
}
|
||||
|
||||
fun getMaxConcurrentDownloads(): Int {
|
||||
|
@ -44,6 +44,7 @@ object ImportHelper {
|
||||
/**
|
||||
* Get a list of channel IDs from a file [Uri]
|
||||
*/
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
private fun getChannelsFromUri(activity: Activity, uri: Uri): List<String> {
|
||||
return when (val fileType = activity.contentResolver.getType(uri)) {
|
||||
"application/json", "application/*", "application/octet-stream" -> {
|
||||
@ -72,6 +73,7 @@ object ImportHelper {
|
||||
/**
|
||||
* Write the text to the document
|
||||
*/
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
suspend fun exportSubscriptions(activity: Activity, uri: Uri) {
|
||||
val token = PreferenceHelper.getToken()
|
||||
val subs = if (token.isNotEmpty()) {
|
||||
@ -149,6 +151,7 @@ object ImportHelper {
|
||||
/**
|
||||
* Export Playlists
|
||||
*/
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
suspend fun exportPlaylists(activity: Activity, uri: Uri) {
|
||||
val playlists = PlaylistsHelper.exportPlaylists()
|
||||
val playlistFile = ImportPlaylistFile("Piped", 1, playlists)
|
||||
|
@ -10,6 +10,7 @@ object NetworkHelper {
|
||||
/**
|
||||
* Detect whether network is available
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
fun isNetworkAvailable(context: Context): Boolean {
|
||||
// In case we are using a VPN, we return true since we might be using reverse tethering
|
||||
val connectivityManager = context.getSystemService<ConnectivityManager>() ?: return false
|
||||
@ -36,6 +37,7 @@ object NetworkHelper {
|
||||
* @param context Context of the application
|
||||
* @return whether the network is metered or not
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
fun isNetworkMetered(context: Context): Boolean {
|
||||
val connectivityManager = context.getSystemService<ConnectivityManager>()!!
|
||||
val activeNetworkInfo = connectivityManager.activeNetworkInfo
|
||||
|
@ -132,7 +132,7 @@ object ThemeHelper {
|
||||
* Get the styled app name
|
||||
*/
|
||||
fun getStyledAppName(context: Context): Spanned {
|
||||
val colorPrimary = getThemeColor(context, R.attr.colorPrimaryDark)
|
||||
val colorPrimary = getThemeColor(context, androidx.appcompat.R.attr.colorPrimaryDark)
|
||||
val hexColor = String.format("#%06X", (0xFFFFFF and colorPrimary))
|
||||
return "Libre<span style='color:$hexColor';>Tube</span>"
|
||||
.parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||
|
@ -57,6 +57,7 @@ import java.nio.file.StandardOpenOption
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.io.path.absolute
|
||||
import kotlin.io.path.createFile
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.io.path.fileSize
|
||||
|
||||
/**
|
||||
@ -103,7 +104,6 @@ class DownloadService : LifecycleService() {
|
||||
}
|
||||
|
||||
val thumbnailTargetPath = getDownloadPath(DownloadHelper.THUMBNAIL_DIR, fileName)
|
||||
.absolute()
|
||||
|
||||
val download = Download(
|
||||
videoId,
|
||||
@ -147,7 +147,7 @@ class DownloadService : LifecycleService() {
|
||||
FileType.AUDIO -> getDownloadPath(DownloadHelper.AUDIO_DIR, item.fileName)
|
||||
FileType.VIDEO -> getDownloadPath(DownloadHelper.VIDEO_DIR, item.fileName)
|
||||
FileType.SUBTITLE -> getDownloadPath(DownloadHelper.SUBTITLE_DIR, item.fileName)
|
||||
}.createFile().absolute()
|
||||
}.apply { deleteIfExists() }.createFile()
|
||||
|
||||
lifecycleScope.launch(coroutineContext) {
|
||||
item.id = Database.downloadDao().insertDownloadItem(item).toInt()
|
||||
@ -440,8 +440,7 @@ class DownloadService : LifecycleService() {
|
||||
* Get a [File] from the corresponding download directory and the file name
|
||||
*/
|
||||
private fun getDownloadPath(directory: String, fileName: String): Path {
|
||||
@Suppress("NewApi") // The Path class is desugared.
|
||||
return DownloadHelper.getDownloadDir(this, directory).resolve(fileName)
|
||||
return DownloadHelper.getDownloadDir(this, directory).resolve(fileName).absolute()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -238,8 +238,14 @@ class MainActivity : BaseActivity() {
|
||||
if (lastSeenVideoIndex < 1) return@observe
|
||||
binding.bottomNav.getOrCreateBadge(R.id.subscriptionsFragment).apply {
|
||||
number = lastSeenVideoIndex
|
||||
backgroundColor = ThemeHelper.getThemeColor(this@MainActivity, R.attr.colorPrimary)
|
||||
badgeTextColor = ThemeHelper.getThemeColor(this@MainActivity, R.attr.colorOnPrimary)
|
||||
backgroundColor = ThemeHelper.getThemeColor(
|
||||
this@MainActivity,
|
||||
androidx.appcompat.R.attr.colorPrimary,
|
||||
)
|
||||
badgeTextColor = ThemeHelper.getThemeColor(
|
||||
this@MainActivity,
|
||||
com.google.android.material.R.attr.colorOnPrimary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,8 +103,9 @@ class CommentsAdapter(
|
||||
// highlight the comment that is being replied to
|
||||
if (comment == comments.firstOrNull()) {
|
||||
root.setBackgroundColor(
|
||||
ThemeHelper.getThemeColor(root.context, R.attr.colorSurface),
|
||||
ThemeHelper.getThemeColor(root.context, com.google.android.material.R.attr.colorSurface),
|
||||
)
|
||||
|
||||
root.updatePadding(top = 20)
|
||||
root.updateLayoutParams<MarginLayoutParams> { bottomMargin = 20 }
|
||||
} else {
|
||||
|
@ -35,12 +35,12 @@ class LegacySubscriptionAdapter(
|
||||
root.setOnClickListener {
|
||||
NavigationHelper.navigateChannel(
|
||||
root.context,
|
||||
subscription.url!!.toID(),
|
||||
subscription.url.toID(),
|
||||
)
|
||||
}
|
||||
|
||||
root.setOnLongClickListener {
|
||||
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name)
|
||||
ChannelOptionsBottomSheet(subscription.url.toID(), subscription.name)
|
||||
.show((root.context as BaseActivity).supportFragmentManager)
|
||||
true
|
||||
}
|
||||
|
@ -40,7 +40,8 @@ class PlaylistsAdapter(
|
||||
// set imageview drawable as empty playlist if imageview empty
|
||||
if (playlist.thumbnail.orEmpty().split("/").size <= 4) {
|
||||
playlistThumbnail.setImageResource(R.drawable.ic_empty_playlist)
|
||||
playlistThumbnail.setBackgroundColor(R.attr.colorSurface)
|
||||
playlistThumbnail
|
||||
.setBackgroundColor(com.google.android.material.R.attr.colorSurface)
|
||||
} else {
|
||||
ImageHelper.loadImage(playlist.thumbnail, playlistThumbnail)
|
||||
}
|
||||
|
@ -38,13 +38,13 @@ class SubscriptionChannelAdapter(
|
||||
NavigationHelper.navigateChannel(root.context, subscription.url)
|
||||
}
|
||||
root.setOnLongClickListener {
|
||||
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name)
|
||||
ChannelOptionsBottomSheet(subscription.url.toID(), subscription.name)
|
||||
.show((root.context as BaseActivity).supportFragmentManager)
|
||||
true
|
||||
}
|
||||
|
||||
subscriptionSubscribe.setupSubscriptionButton(
|
||||
subscription.url?.toID(),
|
||||
subscription.url.toID(),
|
||||
subscription.name,
|
||||
notificationBell,
|
||||
true,
|
||||
|
@ -21,7 +21,7 @@ class ErrorDialog : DialogFragment() {
|
||||
.setTitle(R.string.error_occurred)
|
||||
.setMessage(errorLog)
|
||||
.setNegativeButton(R.string.okay, null)
|
||||
.setPositiveButton(R.string.copy) { _, _ ->
|
||||
.setPositiveButton(androidx.preference.R.string.copy) { _, _ ->
|
||||
ClipboardHelper.save(requireContext(), errorLog)
|
||||
Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class NotificationSettings : BasePreferenceFragment() {
|
||||
NotificationHelper
|
||||
.enqueueWork(
|
||||
context = requireContext(),
|
||||
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.REPLACE,
|
||||
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.UPDATE,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ class CommentsSheet : ExpandedBottomSheet() {
|
||||
|
||||
// BottomSheetDialogFragment passthrough user outside touch event
|
||||
dialog.setOnShowListener {
|
||||
dialog.findViewById<View>(R.id.touch_outside)?.apply {
|
||||
dialog.findViewById<View>(com.google.android.material.R.id.touch_outside)?.apply {
|
||||
setOnTouchListener { v, event ->
|
||||
event.setLocation(event.rawX - v.x, event.rawY - v.y)
|
||||
activity?.dispatchTouchEvent(event)
|
||||
|
@ -7,7 +7,6 @@ import android.view.MotionEvent
|
||||
import android.view.MotionEvent.ACTION_MOVE
|
||||
import android.view.ViewConfiguration
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.helpers.ThemeHelper
|
||||
import com.google.android.material.elevation.SurfaceColors
|
||||
import kotlin.math.abs
|
||||
@ -18,7 +17,9 @@ class CustomSwipeToRefresh(context: Context?, attrs: AttributeSet?) :
|
||||
private var mPrevX = 0f
|
||||
|
||||
init {
|
||||
setColorSchemeColors(ThemeHelper.getThemeColor(this.context, R.attr.colorPrimary))
|
||||
setColorSchemeColors(
|
||||
ThemeHelper.getThemeColor(this.context, androidx.appcompat.R.attr.colorPrimary),
|
||||
)
|
||||
setProgressBackgroundColorSchemeColor(
|
||||
SurfaceColors.getColorForElevation(this.context, 20f),
|
||||
)
|
||||
|
@ -7,7 +7,6 @@ import android.graphics.Rect
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.core.view.marginLeft
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.obj.Segment
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.extensions.dpToPx
|
||||
@ -56,7 +55,10 @@ class MarkableTimeBar(
|
||||
canvas.height - marginY,
|
||||
),
|
||||
Paint().apply {
|
||||
color = ThemeHelper.getThemeColor(context, R.attr.colorOnSecondary)
|
||||
color = ThemeHelper.getThemeColor(
|
||||
context,
|
||||
com.google.android.material.R.attr.colorOnSecondary,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath 'com.android.tools.build:gradle:8.0.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
|
||||
|
@ -14,4 +14,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.enableJetifier=true
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonTransitiveRClass=true
|
||||
android.nonFinalResIds=true
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
Loading…
Reference in New Issue
Block a user