diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a54eda8c8..3fcab124b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 55aed5992..d63d60009 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -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 diff --git a/app/build.gradle b/app/build.gradle index 3abdb8277..8be27ab13 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index c9ea8f734..a168aa319 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -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.* ; +} + +# 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.* ; } +-keep,allowobfuscation interface <1> + +# Keep inherited services. +-if interface * { @retrofit2.http.* ; } +-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.** diff --git a/app/src/main/java/com/github/libretube/api/obj/Streams.kt b/app/src/main/java/com/github/libretube/api/obj/Streams.kt index 79eb584ac..9306507a4 100644 --- a/app/src/main/java/com/github/libretube/api/obj/Streams.kt +++ b/app/src/main/java/com/github/libretube/api/obj/Streams.kt @@ -35,7 +35,6 @@ data class Streams( val uploaderSubscriberCount: Long = 0, val previewFrames: List = emptyList(), ) { - @Suppress("NewApi") // The Paths class is desugared. fun toDownloadItems( videoId: String, fileName: String, diff --git a/app/src/main/java/com/github/libretube/extensions/Path.kt b/app/src/main/java/com/github/libretube/extensions/Path.kt index ecdccfb73..47cef7df9 100644 --- a/app/src/main/java/com/github/libretube/extensions/Path.kt +++ b/app/src/main/java/com/github/libretube/extensions/Path.kt @@ -10,6 +10,5 @@ fun Path.toAndroidUriOrNull(): Uri? { } fun Path.toAndroidUri(): Uri { - @Suppress("NewApi") // The Path class is desugared. return toFile().toUri() } diff --git a/app/src/main/java/com/github/libretube/helpers/DownloadHelper.kt b/app/src/main/java/com/github/libretube/helpers/DownloadHelper.kt index a25983706..519bf3d17 100644 --- a/app/src/main/java/com/github/libretube/helpers/DownloadHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/DownloadHelper.kt @@ -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 { diff --git a/app/src/main/java/com/github/libretube/helpers/ImportHelper.kt b/app/src/main/java/com/github/libretube/helpers/ImportHelper.kt index 79d588ded..332471f7b 100644 --- a/app/src/main/java/com/github/libretube/helpers/ImportHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/ImportHelper.kt @@ -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 { 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) diff --git a/app/src/main/java/com/github/libretube/helpers/NetworkHelper.kt b/app/src/main/java/com/github/libretube/helpers/NetworkHelper.kt index e14562e1f..97295f7af 100644 --- a/app/src/main/java/com/github/libretube/helpers/NetworkHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/NetworkHelper.kt @@ -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() ?: 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()!! val activeNetworkInfo = connectivityManager.activeNetworkInfo diff --git a/app/src/main/java/com/github/libretube/helpers/ThemeHelper.kt b/app/src/main/java/com/github/libretube/helpers/ThemeHelper.kt index 8a3c2ffe2..9bcc52b82 100644 --- a/app/src/main/java/com/github/libretube/helpers/ThemeHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/ThemeHelper.kt @@ -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 "LibreTube" .parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT) diff --git a/app/src/main/java/com/github/libretube/services/DownloadService.kt b/app/src/main/java/com/github/libretube/services/DownloadService.kt index f79f8c100..1a7345e5d 100644 --- a/app/src/main/java/com/github/libretube/services/DownloadService.kt +++ b/app/src/main/java/com/github/libretube/services/DownloadService.kt @@ -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() { diff --git a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt index f0069c6a3..9e2114994 100644 --- a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt @@ -251,8 +251,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, + ) } } } diff --git a/app/src/main/java/com/github/libretube/ui/adapters/CommentsAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/CommentsAdapter.kt index 395910de9..3689fe7b4 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/CommentsAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/CommentsAdapter.kt @@ -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 { bottomMargin = 20 } } else { diff --git a/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt index 14b188f5d..0b5c95686 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt @@ -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 } diff --git a/app/src/main/java/com/github/libretube/ui/adapters/PlaylistsAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/PlaylistsAdapter.kt index 6d30a1153..79b03f5da 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/PlaylistsAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/PlaylistsAdapter.kt @@ -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) } diff --git a/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt index dc2976cb1..12e58ff7d 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt @@ -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, diff --git a/app/src/main/java/com/github/libretube/ui/dialogs/ErrorDialog.kt b/app/src/main/java/com/github/libretube/ui/dialogs/ErrorDialog.kt index 6a71f24f9..76e718f50 100644 --- a/app/src/main/java/com/github/libretube/ui/dialogs/ErrorDialog.kt +++ b/app/src/main/java/com/github/libretube/ui/dialogs/ErrorDialog.kt @@ -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() } diff --git a/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt b/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt index f4cb5204b..cf6e52e98 100644 --- a/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt +++ b/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt @@ -62,8 +62,8 @@ class BackupRestoreSettings : BasePreferenceFragment() { /** * result listeners for importing and exporting playlists */ - private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.GetContent()) { - it?.let { + private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.OpenMultipleDocuments()) { + it?.forEach { CoroutineScope(Dispatchers.IO).launch { ImportHelper.importPlaylists(requireActivity(), it) } @@ -94,7 +94,7 @@ class BackupRestoreSettings : BasePreferenceFragment() { val importPlaylists = findPreference("import_playlists") importPlaylists?.setOnPreferenceClickListener { - getPlaylistsFile.launch("*/*") + getPlaylistsFile.launch(arrayOf("*/*")) true } diff --git a/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt b/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt index 494e017b6..bbd28d713 100644 --- a/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt +++ b/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt @@ -41,7 +41,7 @@ class NotificationSettings : BasePreferenceFragment() { NotificationHelper .enqueueWork( context = requireContext(), - existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.REPLACE, + existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.UPDATE, ) } } diff --git a/app/src/main/java/com/github/libretube/ui/sheets/CommentsSheet.kt b/app/src/main/java/com/github/libretube/ui/sheets/CommentsSheet.kt index a25ca80d3..13b32335b 100644 --- a/app/src/main/java/com/github/libretube/ui/sheets/CommentsSheet.kt +++ b/app/src/main/java/com/github/libretube/ui/sheets/CommentsSheet.kt @@ -102,7 +102,7 @@ class CommentsSheet : ExpandedBottomSheet() { // BottomSheetDialogFragment passthrough user outside touch event dialog.setOnShowListener { - dialog.findViewById(R.id.touch_outside)?.apply { + dialog.findViewById(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) diff --git a/app/src/main/java/com/github/libretube/ui/views/CustomSwipeToRefresh.kt b/app/src/main/java/com/github/libretube/ui/views/CustomSwipeToRefresh.kt index 5296cb4ea..1fe184aeb 100644 --- a/app/src/main/java/com/github/libretube/ui/views/CustomSwipeToRefresh.kt +++ b/app/src/main/java/com/github/libretube/ui/views/CustomSwipeToRefresh.kt @@ -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), ) diff --git a/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt b/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt index 234fc751e..09d26e6e2 100644 --- a/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt +++ b/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt @@ -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, + ) }, ) } diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 7961b83ab..b6c1fce48 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -437,4 +437,5 @@ سجل بحث غير محدود المدة المدة (معكوسة) + تنبيهات للفيديوهات القصيرة \ No newline at end of file diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index b47db28f0..f223d4276 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -348,7 +348,7 @@ Davam et Çimdik nəzarəti Böyütmək/kiçiltmək üçün çimdik jesti istifadə et. - Minimalist Tək Rəngli + Minimalist Saya Ən son videoları oynat Heç nə seçilməyib! Bütöv Bənövşə @@ -425,4 +425,5 @@ Qeyri-məhdud axtarış tarixçəsi Müddət (əks) Müddət + Qısa videolar üçün bildirişlər \ No newline at end of file diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 0f770b725..64623815a 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -428,4 +428,10 @@ Паказаць мініяцюры новых відэа. Уключэнне гэтага прывядзе да спажывання дадатковых даных. Паказваць мініяцюры відэа + Неабмежаваная гісторыя пошуку + Назва плэйліста (А-Я) + Назва плэйліста (Я-А) + Працягласць + Працягласць (перавернута) + Апавяшчэнні для shorts \ No newline at end of file diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 60d50635f..c9462f7fc 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -428,4 +428,5 @@ Neomezená historie vyhledávání Délka (obráceně) Délka + Oznámení pro Shorts \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9ed8da4d7..85408e9f1 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -425,4 +425,5 @@ Unbegrenzter Suchverlauf Dauer (aufsteigend) Dauer (absteigend) + Benachrichtigungen für Shorts \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 4ce216bb7..6239da749 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -72,10 +72,10 @@ Historial Historial de búsqueda Borrar historial - Canciones musicales de YT - Vídeos musicales de YT - Álbumes musicales de YT - Playlists de música de YT + YT Música: Canciones + YT Música: Vídeos + YT Música: Álbumes + YT Música: Listas SponsorBlock Usa la API de https://sponsor.ajay.app Segmento omitido @@ -140,7 +140,7 @@ Precarga Cantidad máxima de segundos de vídeo a almacenar en búfer. Clips de relleno - Música: Sección no musical + Música: Sección sin música Avance/Resumen Para segmentos que detallan contenido futuro sin información adicional. Si incluye clips que solo aparecen aquí, es muy probable que ésta sea la categoría incorrecta. Escenas paralelas que se añaden en tono de humor o de relleno, que no son necesarias para entender el contenido principal del vídeo. @@ -278,8 +278,8 @@ Suscripciones locales Preferencias Instancias personalizadas - Cargar suscripciones en segundo plano - Cargar la lista de suscripciones en segundo plano para evitar que la pestaña se auto-refresque. + Cargar contenido en segundo plano + Cargar contenido de las suscripciones en segundo plano para evitar que la pestaña se auto-refresque. Reproducir el siguiente Barra de navegación Tendencias parece no estar disponible para la región actual. Selecciona otra en la configuración. @@ -353,7 +353,7 @@ ¡Nada seleccionado! Violeta Versátil No se pudieron obtener las instancias disponibles. - Ocultar los videos vistos del feed + Ocultar vídeos vistos No mostrar los vídeos vistos más de un 90% en la pestaña de suscripciones. URL de la lista de reproducción Pausar al salir @@ -428,4 +428,5 @@ Historial de búsqueda ilimitado Duración (invertida) Duración + Notificaciones de Shorts \ No newline at end of file diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 1dad7bda7..dcbc1d499 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -425,4 +425,5 @@ Időtartam Időtartam (fordított) Korlátlan keresési előzmények + Értesítés a rövidekhez \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 69731c6a2..17b3b11f3 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -92,7 +92,7 @@ Kartu akhir dan kredit Info mengikuti dengan akhir video. Bukan untuk kesimpulan dengan info. Saat ada pengingat singkat untuk meminta suka, berlangganan atau mengikuti di tengah konten. Jika panjang atau tentang sesuatu yang spesifik, sebaiknya pakai kategori promosi diri sendiri. - Piped + Disalurkan Putar di latar belakang Lisensi Aksen @@ -422,4 +422,5 @@ Riwayat pencarian tidak terbatas Durasi Durasi (dibalik) + Notifikasi untuk video shorts \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 02e9f86bf..2a878c4c7 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -428,4 +428,5 @@ Cronologia di ricerca infinita Durata Durata (invertito) + Notifiche per gli Short \ No newline at end of file diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 0134f2448..394b8e495 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -431,4 +431,5 @@ היסטוריית חיפושים בלתי מוגבלת משך משך (הפוך) + התראות על קצרצרים \ No newline at end of file diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 49ae2b2fc..8212c5cab 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -275,7 +275,7 @@ କେବଳ ୱାଇଫାଇ ରେ ସଦସ୍ୟତା ରପ୍ତାନି କରନ୍ତୁ ଅନୁବାଦ - ଭୁଲ୍ + ତ୍ରୁଟି ସମୟ କୋଡ୍ ସହିତ ଅଂଶୀଦାର କରନ୍ତୁ ବିବିଧ ପୃଷ୍ଠଭୂମି ସ୍ଥିତି @@ -425,4 +425,5 @@ ଅସୀମିତ ସନ୍ଧାନ ଇତିହାସ ଅବଧି ଅବଧି (ଓଲଟା) + ସର୍ଟସ୍ ପାଇଁ ବିଜ୍ଞପ୍ତି \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 4c9c43707..f10465bae 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -431,4 +431,5 @@ %d nowych filmów %d nowych filmów + Powiadomienia dla krótkich wideo \ No newline at end of file diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index f80015a34..25cdfbeba 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -428,4 +428,5 @@ Histórico de pesquisa ilimitado Duração Duração (invertida) + Notificações de shorts \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 023328247..22e11ab72 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -428,4 +428,5 @@ Histórico de pesquisa ilimitado Duração Duração (invertida) + Notificação para vídeos curtos \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index f20f88fc5..13992836a 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -428,4 +428,5 @@ Istoric de căutare nelimitat Durată Durată (inversată) + Notificări pentru Shorts \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index cc5cf08a7..f94a837fa 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -431,4 +431,5 @@ Неограниченная история поиска Продолжительность (обратная) Продолжительность + Уведомления для shorts \ No newline at end of file diff --git a/app/src/main/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml index 6e600e257..423c24df5 100644 --- a/app/src/main/res/values-si/strings.xml +++ b/app/src/main/res/values-si/strings.xml @@ -423,4 +423,9 @@ නව ප්‍රවාහවල සිඟිති රූ පෙන්වන්න. මෙය සබල කිරීමෙන් අමතර Data වැය වේ. පූර්ණ තිර ඇතුළු වන්න / පිටවන්න අභිනයන් අසීමිත සෙවුම් ඉතිහාසය + වාදන ලැයිස්තු නම (A-Z) + වාදන ලැයිස්තු නම (Z-A) + කාල සීමාව + කාල සීමාව (ප්‍රතිලෝම) + Shorts සඳහා දැනුම්දීම් \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 27827bf75..a6835e10f 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -57,7 +57,7 @@ Додати в добірку Готово. Невдача :( - Про + Про LibreTube Мова Системна Системна @@ -103,7 +103,7 @@ Приємний фіолетовий Material You Сповіщення - Увімкнено + Ввімкнено Вимкнено Поділитися посиланням з Версія %1$s доступна @@ -146,7 +146,7 @@ Відео Автоматичне відтворення Завантаження… - Будь ласка, увімкніть Wi-Fi або мобільний дані для підключення до Інтернету. + Будь ласка, ввімкніть Wi-Fi або мобільний дані для підключення до Інтернету. Відкрити… Відновити стандартні налаштування Стерти всі налаштування і вийти з облікового запису\? @@ -173,8 +173,8 @@ Портретна Назва екземпляра Формат відео для програвача - Сервер аутентифікації - Використовувати інший сервер для аутентифікації. + Сервер автентифікації + Використовувати інший сервер для автентифікації. Співвідношення сторін відео Автоповорот Епізоди @@ -213,7 +213,7 @@ Необхідне з\'єднання Лімітоване Поточний - Зображення в зображенні + Картинка в картинці Показувати значок із кількістю нових відео, якщо такі є. Немає Пропустити вручну @@ -330,7 +330,7 @@ Для регулювання яскравості та гучності використовувати жест посування. Гучність Типові - Спливне вікно + Спливаюче вікно Двічі торкніться, щоб шукати Двічі торкніться ліворуч або праворуч, щоб перемотати назад або вперед. До цього відео немає коментарів. @@ -410,7 +410,7 @@ %1$s • %2$d відео %1$s підписників • %2$d відео Вимкнути транспортний проксі - Завантажуйте відео й зображення безпосередньо з серверів YouTube. Увімкніть цю опцію, якщо ви все одно використовуєте VPN! Зауважте, що це може не спрацювати з матеріалами з YT music. + Завантажуйте відео й зображення безпосередньо з серверів YouTube. Ввімкніть цю опцію, якщо ви все одно використовуєте VPN! Зауважте, що це може не спрацювати з матеріалами з YT music. Автоматичний повноекранний режим для коротких відео Нова Редагувати групу @@ -426,9 +426,10 @@ %d нових трансляцій %d нових трансляцій - Показувати мініатюри нових трансляцій. Увімкнення цієї опції споживає додаткові дані. + Показувати мініатюри нових трансляцій. Ввімкнення цієї опції споживає додаткові дані. Показувати мініатюри трансляцій Необмежена історія запитів Тривалість Тривалість (у зворотному порядку) + Сповіщення для shorts \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2d3c4baee..454d9771d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -422,4 +422,5 @@ 无限搜索历史条目 时长 时长(倒序) + 短视频通知 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 3411f17d0..5271589de 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -188,8 +188,8 @@ 在通知欄顯示附有按鈕的音訊播放器。 尚無歷史紀錄。 通知 - 新串流通知 - 您跟隨的創作者最新串流的通知。 + 顯示新串流通知 + 顯示您跟隨的創作者最新串流的通知。 Wi-Fi 彈出 此視頻沒有評論。 @@ -213,8 +213,8 @@ 時長 開始時間 結束時間 - 通知時長 - 通知顯示的時長。 + 限制通知時間 + 限制串流通知顯示的時間。 下載完成 無法取得可用實例。 播放下一部 @@ -401,4 +401,28 @@ 如果可用,請使用 LBRY HLS 進行流式傳輸。 LBRY HLS 回复 + 播放清單名稱 (A-Z) + 播放清單名稱 (Z-A) + 持續時間 + 持續時間(反轉) + 無限制搜尋歷史紀錄 + 進入/退出全螢幕手勢 + 顯示新串流的縮圖。啟用此選項會消耗更多流量。 + 詳細統計資料 + 短片自動全螢幕 + + %d 個新串流 + + 前往影片 + 停用 Piped 代理伺服器 + 頻道群組 + + 群組名稱 + 編輯群組 + 短片通知 + 顯示串流縮圖 + 直接從 YouTube 的伺服器載入影片與圖片。僅在您使用 VPN 時才啟用此選項!注意,這可能對來自 YouTube 音樂的內容無效。 + 視訊 ID + 自動播放 + 選取時自動開始播放影片 \ No newline at end of file diff --git a/build.gradle b/build.gradle index dee15d07e..7708abf3d 100644 --- a/build.gradle +++ b/build.gradle @@ -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" diff --git a/gradle.properties b/gradle.properties index dcdc79c66..c57869e52 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 \ No newline at end of file +android.enableJetifier=true +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=true +android.nonFinalResIds=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b230eecce..9c76989da 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] appcompat = "1.6.1" -core = "1.10.0" +core = "1.10.1" lifecycle = "2.6.1" constraintlayout = "2.1.4" material = "1.9.0" @@ -18,7 +18,7 @@ cronetOkHttp = "0.1.0" coil = "2.3.0" leakcanary = "2.10" room = "2.5.1" -kotlinxSerialization = "1.5.0" +kotlinxSerialization = "1.5.1" kotlinxDatetime = "0.4.0" kotlinxRetrofit = "1.0.0" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa..c1962a79e 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f398c33c4..37aef8d3f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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.1.1-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68d6..aeb74cbb4 100755 --- a/gradlew +++ b/gradlew @@ -85,9 +85,6 @@ done APP_BASE_NAME=${0##*/} APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +141,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +149,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in