mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 14:20:30 +05:30
Merge branch 'master' into master
This commit is contained in:
commit
9a0bc80c76
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -33,10 +33,10 @@ jobs:
|
|||||||
python checkrun.py
|
python checkrun.py
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 17
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
cache: "gradle"
|
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
|
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
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.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v2
|
||||||
|
@ -53,11 +53,11 @@ android {
|
|||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
coreLibraryDesugaringEnabled true
|
coreLibraryDesugaringEnabled true
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
splits {
|
splits {
|
||||||
abi {
|
abi {
|
||||||
|
54
app/proguard-rules.pro
vendored
54
app/proguard-rules.pro
vendored
@ -52,3 +52,57 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
|
-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 uploaderSubscriberCount: Long = 0,
|
||||||
val previewFrames: List<PreviewFrames> = emptyList(),
|
val previewFrames: List<PreviewFrames> = emptyList(),
|
||||||
) {
|
) {
|
||||||
@Suppress("NewApi") // The Paths class is desugared.
|
|
||||||
fun toDownloadItems(
|
fun toDownloadItems(
|
||||||
videoId: String,
|
videoId: String,
|
||||||
fileName: String,
|
fileName: String,
|
||||||
|
@ -10,6 +10,5 @@ fun Path.toAndroidUriOrNull(): Uri? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Path.toAndroidUri(): Uri {
|
fun Path.toAndroidUri(): Uri {
|
||||||
@Suppress("NewApi") // The Path class is desugared.
|
|
||||||
return toFile().toUri()
|
return toFile().toUri()
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import com.github.libretube.constants.PreferenceKeys
|
|||||||
import com.github.libretube.db.obj.DownloadItem
|
import com.github.libretube.db.obj.DownloadItem
|
||||||
import com.github.libretube.services.DownloadService
|
import com.github.libretube.services.DownloadService
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.createDirectories
|
|
||||||
|
|
||||||
object DownloadHelper {
|
object DownloadHelper {
|
||||||
const val VIDEO_DIR = "video"
|
const val VIDEO_DIR = "video"
|
||||||
@ -35,8 +34,11 @@ object DownloadHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getDownloadDir(context: Context, path: String): Path {
|
fun getDownloadDir(context: Context, path: String): Path {
|
||||||
@Suppress("NewApi") // The Path class is desugared.
|
// TODO: Use createDirectories() when https://issuetracker.google.com/issues/279034662 is
|
||||||
return getOfflineStorageDir(context).resolve(path).createDirectories()
|
// fixed.
|
||||||
|
return getOfflineStorageDir(context).resolve(path).apply {
|
||||||
|
toFile().mkdirs()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMaxConcurrentDownloads(): Int {
|
fun getMaxConcurrentDownloads(): Int {
|
||||||
|
@ -44,6 +44,7 @@ object ImportHelper {
|
|||||||
/**
|
/**
|
||||||
* Get a list of channel IDs from a file [Uri]
|
* Get a list of channel IDs from a file [Uri]
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
private fun getChannelsFromUri(activity: Activity, uri: Uri): List<String> {
|
private fun getChannelsFromUri(activity: Activity, uri: Uri): List<String> {
|
||||||
return when (val fileType = activity.contentResolver.getType(uri)) {
|
return when (val fileType = activity.contentResolver.getType(uri)) {
|
||||||
"application/json", "application/*", "application/octet-stream" -> {
|
"application/json", "application/*", "application/octet-stream" -> {
|
||||||
@ -72,6 +73,7 @@ object ImportHelper {
|
|||||||
/**
|
/**
|
||||||
* Write the text to the document
|
* Write the text to the document
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
suspend fun exportSubscriptions(activity: Activity, uri: Uri) {
|
suspend fun exportSubscriptions(activity: Activity, uri: Uri) {
|
||||||
val token = PreferenceHelper.getToken()
|
val token = PreferenceHelper.getToken()
|
||||||
val subs = if (token.isNotEmpty()) {
|
val subs = if (token.isNotEmpty()) {
|
||||||
@ -149,6 +151,7 @@ object ImportHelper {
|
|||||||
/**
|
/**
|
||||||
* Export Playlists
|
* Export Playlists
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
suspend fun exportPlaylists(activity: Activity, uri: Uri) {
|
suspend fun exportPlaylists(activity: Activity, uri: Uri) {
|
||||||
val playlists = PlaylistsHelper.exportPlaylists()
|
val playlists = PlaylistsHelper.exportPlaylists()
|
||||||
val playlistFile = ImportPlaylistFile("Piped", 1, playlists)
|
val playlistFile = ImportPlaylistFile("Piped", 1, playlists)
|
||||||
|
@ -10,6 +10,7 @@ object NetworkHelper {
|
|||||||
/**
|
/**
|
||||||
* Detect whether network is available
|
* Detect whether network is available
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
fun isNetworkAvailable(context: Context): Boolean {
|
fun isNetworkAvailable(context: Context): Boolean {
|
||||||
// In case we are using a VPN, we return true since we might be using reverse tethering
|
// In case we are using a VPN, we return true since we might be using reverse tethering
|
||||||
val connectivityManager = context.getSystemService<ConnectivityManager>() ?: return false
|
val connectivityManager = context.getSystemService<ConnectivityManager>() ?: return false
|
||||||
@ -36,6 +37,7 @@ object NetworkHelper {
|
|||||||
* @param context Context of the application
|
* @param context Context of the application
|
||||||
* @return whether the network is metered or not
|
* @return whether the network is metered or not
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
fun isNetworkMetered(context: Context): Boolean {
|
fun isNetworkMetered(context: Context): Boolean {
|
||||||
val connectivityManager = context.getSystemService<ConnectivityManager>()!!
|
val connectivityManager = context.getSystemService<ConnectivityManager>()!!
|
||||||
val activeNetworkInfo = connectivityManager.activeNetworkInfo
|
val activeNetworkInfo = connectivityManager.activeNetworkInfo
|
||||||
|
@ -132,7 +132,7 @@ object ThemeHelper {
|
|||||||
* Get the styled app name
|
* Get the styled app name
|
||||||
*/
|
*/
|
||||||
fun getStyledAppName(context: Context): Spanned {
|
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))
|
val hexColor = String.format("#%06X", (0xFFFFFF and colorPrimary))
|
||||||
return "Libre<span style='color:$hexColor';>Tube</span>"
|
return "Libre<span style='color:$hexColor';>Tube</span>"
|
||||||
.parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT)
|
.parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||||
|
@ -57,6 +57,7 @@ import java.nio.file.StandardOpenOption
|
|||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.io.path.absolute
|
import kotlin.io.path.absolute
|
||||||
import kotlin.io.path.createFile
|
import kotlin.io.path.createFile
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
import kotlin.io.path.fileSize
|
import kotlin.io.path.fileSize
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,7 +104,6 @@ class DownloadService : LifecycleService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val thumbnailTargetPath = getDownloadPath(DownloadHelper.THUMBNAIL_DIR, fileName)
|
val thumbnailTargetPath = getDownloadPath(DownloadHelper.THUMBNAIL_DIR, fileName)
|
||||||
.absolute()
|
|
||||||
|
|
||||||
val download = Download(
|
val download = Download(
|
||||||
videoId,
|
videoId,
|
||||||
@ -147,7 +147,7 @@ class DownloadService : LifecycleService() {
|
|||||||
FileType.AUDIO -> getDownloadPath(DownloadHelper.AUDIO_DIR, item.fileName)
|
FileType.AUDIO -> getDownloadPath(DownloadHelper.AUDIO_DIR, item.fileName)
|
||||||
FileType.VIDEO -> getDownloadPath(DownloadHelper.VIDEO_DIR, item.fileName)
|
FileType.VIDEO -> getDownloadPath(DownloadHelper.VIDEO_DIR, item.fileName)
|
||||||
FileType.SUBTITLE -> getDownloadPath(DownloadHelper.SUBTITLE_DIR, item.fileName)
|
FileType.SUBTITLE -> getDownloadPath(DownloadHelper.SUBTITLE_DIR, item.fileName)
|
||||||
}.createFile().absolute()
|
}.apply { deleteIfExists() }.createFile()
|
||||||
|
|
||||||
lifecycleScope.launch(coroutineContext) {
|
lifecycleScope.launch(coroutineContext) {
|
||||||
item.id = Database.downloadDao().insertDownloadItem(item).toInt()
|
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
|
* Get a [File] from the corresponding download directory and the file name
|
||||||
*/
|
*/
|
||||||
private fun getDownloadPath(directory: String, fileName: String): Path {
|
private fun getDownloadPath(directory: String, fileName: String): Path {
|
||||||
@Suppress("NewApi") // The Path class is desugared.
|
return DownloadHelper.getDownloadDir(this, directory).resolve(fileName).absolute()
|
||||||
return DownloadHelper.getDownloadDir(this, directory).resolve(fileName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
@ -251,8 +251,14 @@ class MainActivity : BaseActivity() {
|
|||||||
if (lastSeenVideoIndex < 1) return@observe
|
if (lastSeenVideoIndex < 1) return@observe
|
||||||
binding.bottomNav.getOrCreateBadge(R.id.subscriptionsFragment).apply {
|
binding.bottomNav.getOrCreateBadge(R.id.subscriptionsFragment).apply {
|
||||||
number = lastSeenVideoIndex
|
number = lastSeenVideoIndex
|
||||||
backgroundColor = ThemeHelper.getThemeColor(this@MainActivity, R.attr.colorPrimary)
|
backgroundColor = ThemeHelper.getThemeColor(
|
||||||
badgeTextColor = ThemeHelper.getThemeColor(this@MainActivity, R.attr.colorOnPrimary)
|
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
|
// highlight the comment that is being replied to
|
||||||
if (comment == comments.firstOrNull()) {
|
if (comment == comments.firstOrNull()) {
|
||||||
root.setBackgroundColor(
|
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.updatePadding(top = 20)
|
||||||
root.updateLayoutParams<MarginLayoutParams> { bottomMargin = 20 }
|
root.updateLayoutParams<MarginLayoutParams> { bottomMargin = 20 }
|
||||||
} else {
|
} else {
|
||||||
|
@ -35,12 +35,12 @@ class LegacySubscriptionAdapter(
|
|||||||
root.setOnClickListener {
|
root.setOnClickListener {
|
||||||
NavigationHelper.navigateChannel(
|
NavigationHelper.navigateChannel(
|
||||||
root.context,
|
root.context,
|
||||||
subscription.url!!.toID(),
|
subscription.url.toID(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
root.setOnLongClickListener {
|
root.setOnLongClickListener {
|
||||||
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name)
|
ChannelOptionsBottomSheet(subscription.url.toID(), subscription.name)
|
||||||
.show((root.context as BaseActivity).supportFragmentManager)
|
.show((root.context as BaseActivity).supportFragmentManager)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,8 @@ class PlaylistsAdapter(
|
|||||||
// set imageview drawable as empty playlist if imageview empty
|
// set imageview drawable as empty playlist if imageview empty
|
||||||
if (playlist.thumbnail.orEmpty().split("/").size <= 4) {
|
if (playlist.thumbnail.orEmpty().split("/").size <= 4) {
|
||||||
playlistThumbnail.setImageResource(R.drawable.ic_empty_playlist)
|
playlistThumbnail.setImageResource(R.drawable.ic_empty_playlist)
|
||||||
playlistThumbnail.setBackgroundColor(R.attr.colorSurface)
|
playlistThumbnail
|
||||||
|
.setBackgroundColor(com.google.android.material.R.attr.colorSurface)
|
||||||
} else {
|
} else {
|
||||||
ImageHelper.loadImage(playlist.thumbnail, playlistThumbnail)
|
ImageHelper.loadImage(playlist.thumbnail, playlistThumbnail)
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@ class SubscriptionChannelAdapter(
|
|||||||
NavigationHelper.navigateChannel(root.context, subscription.url)
|
NavigationHelper.navigateChannel(root.context, subscription.url)
|
||||||
}
|
}
|
||||||
root.setOnLongClickListener {
|
root.setOnLongClickListener {
|
||||||
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name)
|
ChannelOptionsBottomSheet(subscription.url.toID(), subscription.name)
|
||||||
.show((root.context as BaseActivity).supportFragmentManager)
|
.show((root.context as BaseActivity).supportFragmentManager)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptionSubscribe.setupSubscriptionButton(
|
subscriptionSubscribe.setupSubscriptionButton(
|
||||||
subscription.url?.toID(),
|
subscription.url.toID(),
|
||||||
subscription.name,
|
subscription.name,
|
||||||
notificationBell,
|
notificationBell,
|
||||||
true,
|
true,
|
||||||
|
@ -21,7 +21,7 @@ class ErrorDialog : DialogFragment() {
|
|||||||
.setTitle(R.string.error_occurred)
|
.setTitle(R.string.error_occurred)
|
||||||
.setMessage(errorLog)
|
.setMessage(errorLog)
|
||||||
.setNegativeButton(R.string.okay, null)
|
.setNegativeButton(R.string.okay, null)
|
||||||
.setPositiveButton(R.string.copy) { _, _ ->
|
.setPositiveButton(androidx.preference.R.string.copy) { _, _ ->
|
||||||
ClipboardHelper.save(requireContext(), errorLog)
|
ClipboardHelper.save(requireContext(), errorLog)
|
||||||
Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,8 @@ class BackupRestoreSettings : BasePreferenceFragment() {
|
|||||||
/**
|
/**
|
||||||
* result listeners for importing and exporting playlists
|
* result listeners for importing and exporting playlists
|
||||||
*/
|
*/
|
||||||
private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.GetContent()) {
|
private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.OpenMultipleDocuments()) {
|
||||||
it?.let {
|
it?.forEach {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
ImportHelper.importPlaylists(requireActivity(), it)
|
ImportHelper.importPlaylists(requireActivity(), it)
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ class BackupRestoreSettings : BasePreferenceFragment() {
|
|||||||
|
|
||||||
val importPlaylists = findPreference<Preference>("import_playlists")
|
val importPlaylists = findPreference<Preference>("import_playlists")
|
||||||
importPlaylists?.setOnPreferenceClickListener {
|
importPlaylists?.setOnPreferenceClickListener {
|
||||||
getPlaylistsFile.launch("*/*")
|
getPlaylistsFile.launch(arrayOf("*/*"))
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class NotificationSettings : BasePreferenceFragment() {
|
|||||||
NotificationHelper
|
NotificationHelper
|
||||||
.enqueueWork(
|
.enqueueWork(
|
||||||
context = requireContext(),
|
context = requireContext(),
|
||||||
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.REPLACE,
|
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.UPDATE,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ class CommentsSheet : ExpandedBottomSheet() {
|
|||||||
|
|
||||||
// BottomSheetDialogFragment passthrough user outside touch event
|
// BottomSheetDialogFragment passthrough user outside touch event
|
||||||
dialog.setOnShowListener {
|
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 ->
|
setOnTouchListener { v, event ->
|
||||||
event.setLocation(event.rawX - v.x, event.rawY - v.y)
|
event.setLocation(event.rawX - v.x, event.rawY - v.y)
|
||||||
activity?.dispatchTouchEvent(event)
|
activity?.dispatchTouchEvent(event)
|
||||||
|
@ -7,7 +7,6 @@ import android.view.MotionEvent
|
|||||||
import android.view.MotionEvent.ACTION_MOVE
|
import android.view.MotionEvent.ACTION_MOVE
|
||||||
import android.view.ViewConfiguration
|
import android.view.ViewConfiguration
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.github.libretube.R
|
|
||||||
import com.github.libretube.helpers.ThemeHelper
|
import com.github.libretube.helpers.ThemeHelper
|
||||||
import com.google.android.material.elevation.SurfaceColors
|
import com.google.android.material.elevation.SurfaceColors
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
@ -18,7 +17,9 @@ class CustomSwipeToRefresh(context: Context?, attrs: AttributeSet?) :
|
|||||||
private var mPrevX = 0f
|
private var mPrevX = 0f
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setColorSchemeColors(ThemeHelper.getThemeColor(this.context, R.attr.colorPrimary))
|
setColorSchemeColors(
|
||||||
|
ThemeHelper.getThemeColor(this.context, androidx.appcompat.R.attr.colorPrimary),
|
||||||
|
)
|
||||||
setProgressBackgroundColorSchemeColor(
|
setProgressBackgroundColorSchemeColor(
|
||||||
SurfaceColors.getColorForElevation(this.context, 20f),
|
SurfaceColors.getColorForElevation(this.context, 20f),
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,6 @@ import android.graphics.Rect
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.view.marginLeft
|
import androidx.core.view.marginLeft
|
||||||
import com.github.libretube.R
|
|
||||||
import com.github.libretube.api.obj.Segment
|
import com.github.libretube.api.obj.Segment
|
||||||
import com.github.libretube.constants.PreferenceKeys
|
import com.github.libretube.constants.PreferenceKeys
|
||||||
import com.github.libretube.extensions.dpToPx
|
import com.github.libretube.extensions.dpToPx
|
||||||
@ -56,7 +55,10 @@ class MarkableTimeBar(
|
|||||||
canvas.height - marginY,
|
canvas.height - marginY,
|
||||||
),
|
),
|
||||||
Paint().apply {
|
Paint().apply {
|
||||||
color = ThemeHelper.getThemeColor(context, R.attr.colorOnSecondary)
|
color = ThemeHelper.getThemeColor(
|
||||||
|
context,
|
||||||
|
com.google.android.material.R.attr.colorOnSecondary,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -437,4 +437,5 @@
|
|||||||
<string name="unlimited_search_history">سجل بحث غير محدود</string>
|
<string name="unlimited_search_history">سجل بحث غير محدود</string>
|
||||||
<string name="duration">المدة</string>
|
<string name="duration">المدة</string>
|
||||||
<string name="duration_reversed">المدة (معكوسة)</string>
|
<string name="duration_reversed">المدة (معكوسة)</string>
|
||||||
|
<string name="shorts_notifications">تنبيهات للفيديوهات القصيرة</string>
|
||||||
</resources>
|
</resources>
|
@ -348,7 +348,7 @@
|
|||||||
<string name="proceed">Davam et</string>
|
<string name="proceed">Davam et</string>
|
||||||
<string name="pinch_control">Çimdik nəzarəti</string>
|
<string name="pinch_control">Çimdik nəzarəti</string>
|
||||||
<string name="pinch_control_summary">Böyütmək/kiçiltmək üçün çimdik jesti istifadə et.</string>
|
<string name="pinch_control_summary">Böyütmək/kiçiltmək üçün çimdik jesti istifadə et.</string>
|
||||||
<string name="theme_monochrome">Minimalist Tək Rəngli</string>
|
<string name="theme_monochrome">Minimalist Saya</string>
|
||||||
<string name="play_latest_videos">Ən son videoları oynat</string>
|
<string name="play_latest_videos">Ən son videoları oynat</string>
|
||||||
<string name="nothing_selected">Heç nə seçilməyib!</string>
|
<string name="nothing_selected">Heç nə seçilməyib!</string>
|
||||||
<string name="color_violet">Bütöv Bənövşə</string>
|
<string name="color_violet">Bütöv Bənövşə</string>
|
||||||
@ -425,4 +425,5 @@
|
|||||||
<string name="unlimited_search_history">Qeyri-məhdud axtarış tarixçəsi</string>
|
<string name="unlimited_search_history">Qeyri-məhdud axtarış tarixçəsi</string>
|
||||||
<string name="duration_reversed">Müddət (əks)</string>
|
<string name="duration_reversed">Müddət (əks)</string>
|
||||||
<string name="duration">Müddət</string>
|
<string name="duration">Müddət</string>
|
||||||
|
<string name="shorts_notifications">Qısa videolar üçün bildirişlər</string>
|
||||||
</resources>
|
</resources>
|
@ -428,4 +428,10 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="show_stream_thumbnails_summary">Паказаць мініяцюры новых відэа. Уключэнне гэтага прывядзе да спажывання дадатковых даных.</string>
|
<string name="show_stream_thumbnails_summary">Паказаць мініяцюры новых відэа. Уключэнне гэтага прывядзе да спажывання дадатковых даных.</string>
|
||||||
<string name="show_stream_thumbnails">Паказваць мініяцюры відэа</string>
|
<string name="show_stream_thumbnails">Паказваць мініяцюры відэа</string>
|
||||||
|
<string name="unlimited_search_history">Неабмежаваная гісторыя пошуку</string>
|
||||||
|
<string name="playlist_name_az">Назва плэйліста (А-Я)</string>
|
||||||
|
<string name="playlist_name_za">Назва плэйліста (Я-А)</string>
|
||||||
|
<string name="duration">Працягласць</string>
|
||||||
|
<string name="duration_reversed">Працягласць (перавернута)</string>
|
||||||
|
<string name="shorts_notifications">Апавяшчэнні для shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -428,4 +428,5 @@
|
|||||||
<string name="unlimited_search_history">Neomezená historie vyhledávání</string>
|
<string name="unlimited_search_history">Neomezená historie vyhledávání</string>
|
||||||
<string name="duration_reversed">Délka (obráceně)</string>
|
<string name="duration_reversed">Délka (obráceně)</string>
|
||||||
<string name="duration">Délka</string>
|
<string name="duration">Délka</string>
|
||||||
|
<string name="shorts_notifications">Oznámení pro Shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -425,4 +425,5 @@
|
|||||||
<string name="unlimited_search_history">Unbegrenzter Suchverlauf</string>
|
<string name="unlimited_search_history">Unbegrenzter Suchverlauf</string>
|
||||||
<string name="duration">Dauer (aufsteigend)</string>
|
<string name="duration">Dauer (aufsteigend)</string>
|
||||||
<string name="duration_reversed">Dauer (absteigend)</string>
|
<string name="duration_reversed">Dauer (absteigend)</string>
|
||||||
|
<string name="shorts_notifications">Benachrichtigungen für Shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -72,10 +72,10 @@
|
|||||||
<string name="history">Historial</string>
|
<string name="history">Historial</string>
|
||||||
<string name="search_history">Historial de búsqueda</string>
|
<string name="search_history">Historial de búsqueda</string>
|
||||||
<string name="clear_history">Borrar historial</string>
|
<string name="clear_history">Borrar historial</string>
|
||||||
<string name="music_songs">Canciones musicales de YT</string>
|
<string name="music_songs">YT Música: Canciones</string>
|
||||||
<string name="music_videos">Vídeos musicales de YT</string>
|
<string name="music_videos">YT Música: Vídeos</string>
|
||||||
<string name="music_albums">Álbumes musicales de YT</string>
|
<string name="music_albums">YT Música: Álbumes</string>
|
||||||
<string name="music_playlists">Playlists de música de YT</string>
|
<string name="music_playlists">YT Música: Listas</string>
|
||||||
<string name="sponsorblock">SponsorBlock</string>
|
<string name="sponsorblock">SponsorBlock</string>
|
||||||
<string name="sponsorblock_summary">Usa la API de https://sponsor.ajay.app</string>
|
<string name="sponsorblock_summary">Usa la API de https://sponsor.ajay.app</string>
|
||||||
<string name="segment_skipped">Segmento omitido</string>
|
<string name="segment_skipped">Segmento omitido</string>
|
||||||
@ -140,7 +140,7 @@
|
|||||||
<string name="buffering_goal">Precarga</string>
|
<string name="buffering_goal">Precarga</string>
|
||||||
<string name="buffering_goal_summary">Cantidad máxima de segundos de vídeo a almacenar en búfer.</string>
|
<string name="buffering_goal_summary">Cantidad máxima de segundos de vídeo a almacenar en búfer.</string>
|
||||||
<string name="category_filler">Clips de relleno</string>
|
<string name="category_filler">Clips de relleno</string>
|
||||||
<string name="category_music_offtopic">Música: Sección no musical</string>
|
<string name="category_music_offtopic">Música: Sección sin música</string>
|
||||||
<string name="category_preview">Avance/Resumen</string>
|
<string name="category_preview">Avance/Resumen</string>
|
||||||
<string name="category_preview_description">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.</string>
|
<string name="category_preview_description">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.</string>
|
||||||
<string name="category_filler_description">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.</string>
|
<string name="category_filler_description">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.</string>
|
||||||
@ -278,8 +278,8 @@
|
|||||||
<string name="local_subscriptions">Suscripciones locales</string>
|
<string name="local_subscriptions">Suscripciones locales</string>
|
||||||
<string name="preferences">Preferencias</string>
|
<string name="preferences">Preferencias</string>
|
||||||
<string name="backup_customInstances">Instancias personalizadas</string>
|
<string name="backup_customInstances">Instancias personalizadas</string>
|
||||||
<string name="save_feed">Cargar suscripciones en segundo plano</string>
|
<string name="save_feed">Cargar contenido en segundo plano</string>
|
||||||
<string name="save_feed_summary">Cargar la lista de suscripciones en segundo plano para evitar que la pestaña se auto-refresque.</string>
|
<string name="save_feed_summary">Cargar contenido de las suscripciones en segundo plano para evitar que la pestaña se auto-refresque.</string>
|
||||||
<string name="play_next">Reproducir el siguiente</string>
|
<string name="play_next">Reproducir el siguiente</string>
|
||||||
<string name="navigation_bar">Barra de navegación</string>
|
<string name="navigation_bar">Barra de navegación</string>
|
||||||
<string name="change_region">Tendencias parece no estar disponible para la región actual. Selecciona otra en la configuración.</string>
|
<string name="change_region">Tendencias parece no estar disponible para la región actual. Selecciona otra en la configuración.</string>
|
||||||
@ -353,7 +353,7 @@
|
|||||||
<string name="nothing_selected">¡Nada seleccionado!</string>
|
<string name="nothing_selected">¡Nada seleccionado!</string>
|
||||||
<string name="color_violet">Violeta Versátil</string>
|
<string name="color_violet">Violeta Versátil</string>
|
||||||
<string name="failed_fetching_instances">No se pudieron obtener las instancias disponibles.</string>
|
<string name="failed_fetching_instances">No se pudieron obtener las instancias disponibles.</string>
|
||||||
<string name="hide_watched_from_feed">Ocultar los videos vistos del feed</string>
|
<string name="hide_watched_from_feed">Ocultar vídeos vistos</string>
|
||||||
<string name="hide_watched_from_feed_summary">No mostrar los vídeos vistos más de un 90% en la pestaña de suscripciones.</string>
|
<string name="hide_watched_from_feed_summary">No mostrar los vídeos vistos más de un 90% en la pestaña de suscripciones.</string>
|
||||||
<string name="playlistUrl">URL de la lista de reproducción</string>
|
<string name="playlistUrl">URL de la lista de reproducción</string>
|
||||||
<string name="pause_on_quit">Pausar al salir</string>
|
<string name="pause_on_quit">Pausar al salir</string>
|
||||||
@ -428,4 +428,5 @@
|
|||||||
<string name="unlimited_search_history">Historial de búsqueda ilimitado</string>
|
<string name="unlimited_search_history">Historial de búsqueda ilimitado</string>
|
||||||
<string name="duration_reversed">Duración (invertida)</string>
|
<string name="duration_reversed">Duración (invertida)</string>
|
||||||
<string name="duration">Duración</string>
|
<string name="duration">Duración</string>
|
||||||
|
<string name="shorts_notifications">Notificaciones de Shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -425,4 +425,5 @@
|
|||||||
<string name="duration">Időtartam</string>
|
<string name="duration">Időtartam</string>
|
||||||
<string name="duration_reversed">Időtartam (fordított)</string>
|
<string name="duration_reversed">Időtartam (fordított)</string>
|
||||||
<string name="unlimited_search_history">Korlátlan keresési előzmények</string>
|
<string name="unlimited_search_history">Korlátlan keresési előzmények</string>
|
||||||
|
<string name="shorts_notifications">Értesítés a rövidekhez</string>
|
||||||
</resources>
|
</resources>
|
@ -92,7 +92,7 @@
|
|||||||
<string name="category_outro">Kartu akhir dan kredit</string>
|
<string name="category_outro">Kartu akhir dan kredit</string>
|
||||||
<string name="category_outro_description">Info mengikuti dengan akhir video. Bukan untuk kesimpulan dengan info.</string>
|
<string name="category_outro_description">Info mengikuti dengan akhir video. Bukan untuk kesimpulan dengan info.</string>
|
||||||
<string name="category_interaction_description">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.</string>
|
<string name="category_interaction_description">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.</string>
|
||||||
<string name="piped">Piped</string>
|
<string name="piped">Disalurkan</string>
|
||||||
<string name="playOnBackground">Putar di latar belakang</string>
|
<string name="playOnBackground">Putar di latar belakang</string>
|
||||||
<string name="license">Lisensi</string>
|
<string name="license">Lisensi</string>
|
||||||
<string name="color_accent">Aksen</string>
|
<string name="color_accent">Aksen</string>
|
||||||
@ -422,4 +422,5 @@
|
|||||||
<string name="unlimited_search_history">Riwayat pencarian tidak terbatas</string>
|
<string name="unlimited_search_history">Riwayat pencarian tidak terbatas</string>
|
||||||
<string name="duration">Durasi</string>
|
<string name="duration">Durasi</string>
|
||||||
<string name="duration_reversed">Durasi (dibalik)</string>
|
<string name="duration_reversed">Durasi (dibalik)</string>
|
||||||
|
<string name="shorts_notifications">Notifikasi untuk video shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -428,4 +428,5 @@
|
|||||||
<string name="unlimited_search_history">Cronologia di ricerca infinita</string>
|
<string name="unlimited_search_history">Cronologia di ricerca infinita</string>
|
||||||
<string name="duration">Durata</string>
|
<string name="duration">Durata</string>
|
||||||
<string name="duration_reversed">Durata (invertito)</string>
|
<string name="duration_reversed">Durata (invertito)</string>
|
||||||
|
<string name="shorts_notifications">Notifiche per gli Short</string>
|
||||||
</resources>
|
</resources>
|
@ -431,4 +431,5 @@
|
|||||||
<string name="unlimited_search_history">היסטוריית חיפושים בלתי מוגבלת</string>
|
<string name="unlimited_search_history">היסטוריית חיפושים בלתי מוגבלת</string>
|
||||||
<string name="duration">משך</string>
|
<string name="duration">משך</string>
|
||||||
<string name="duration_reversed">משך (הפוך)</string>
|
<string name="duration_reversed">משך (הפוך)</string>
|
||||||
|
<string name="shorts_notifications">התראות על קצרצרים</string>
|
||||||
</resources>
|
</resources>
|
@ -275,7 +275,7 @@
|
|||||||
<string name="network_wifi">କେବଳ ୱାଇଫାଇ ରେ</string>
|
<string name="network_wifi">କେବଳ ୱାଇଫାଇ ରେ</string>
|
||||||
<string name="export_subscriptions">ସଦସ୍ୟତା ରପ୍ତାନି କରନ୍ତୁ</string>
|
<string name="export_subscriptions">ସଦସ୍ୟତା ରପ୍ତାନି କରନ୍ତୁ</string>
|
||||||
<string name="translate">ଅନୁବାଦ</string>
|
<string name="translate">ଅନୁବାଦ</string>
|
||||||
<string name="error_occurred">ଭୁଲ୍</string>
|
<string name="error_occurred">ତ୍ରୁଟି</string>
|
||||||
<string name="share_with_time">ସମୟ କୋଡ୍ ସହିତ ଅଂଶୀଦାର କରନ୍ତୁ</string>
|
<string name="share_with_time">ସମୟ କୋଡ୍ ସହିତ ଅଂଶୀଦାର କରନ୍ତୁ</string>
|
||||||
<string name="misc">ବିବିଧ</string>
|
<string name="misc">ବିବିଧ</string>
|
||||||
<string name="background_mode">ପୃଷ୍ଠଭୂମି ସ୍ଥିତି</string>
|
<string name="background_mode">ପୃଷ୍ଠଭୂମି ସ୍ଥିତି</string>
|
||||||
@ -425,4 +425,5 @@
|
|||||||
<string name="unlimited_search_history">ଅସୀମିତ ସନ୍ଧାନ ଇତିହାସ</string>
|
<string name="unlimited_search_history">ଅସୀମିତ ସନ୍ଧାନ ଇତିହାସ</string>
|
||||||
<string name="duration">ଅବଧି</string>
|
<string name="duration">ଅବଧି</string>
|
||||||
<string name="duration_reversed">ଅବଧି (ଓଲଟା)</string>
|
<string name="duration_reversed">ଅବଧି (ଓଲଟା)</string>
|
||||||
|
<string name="shorts_notifications">ସର୍ଟସ୍ ପାଇଁ ବିଜ୍ଞପ୍ତି</string>
|
||||||
</resources>
|
</resources>
|
@ -431,4 +431,5 @@
|
|||||||
<item quantity="many">%d nowych filmów</item>
|
<item quantity="many">%d nowych filmów</item>
|
||||||
<item quantity="other">%d nowych filmów</item>
|
<item quantity="other">%d nowych filmów</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<string name="shorts_notifications">Powiadomienia dla krótkich wideo</string>
|
||||||
</resources>
|
</resources>
|
@ -428,4 +428,5 @@
|
|||||||
<string name="unlimited_search_history">Histórico de pesquisa ilimitado</string>
|
<string name="unlimited_search_history">Histórico de pesquisa ilimitado</string>
|
||||||
<string name="duration">Duração</string>
|
<string name="duration">Duração</string>
|
||||||
<string name="duration_reversed">Duração (invertida)</string>
|
<string name="duration_reversed">Duração (invertida)</string>
|
||||||
|
<string name="shorts_notifications">Notificações de shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -428,4 +428,5 @@
|
|||||||
<string name="unlimited_search_history">Histórico de pesquisa ilimitado</string>
|
<string name="unlimited_search_history">Histórico de pesquisa ilimitado</string>
|
||||||
<string name="duration">Duração</string>
|
<string name="duration">Duração</string>
|
||||||
<string name="duration_reversed">Duração (invertida)</string>
|
<string name="duration_reversed">Duração (invertida)</string>
|
||||||
|
<string name="shorts_notifications">Notificação para vídeos curtos</string>
|
||||||
</resources>
|
</resources>
|
@ -428,4 +428,5 @@
|
|||||||
<string name="unlimited_search_history">Istoric de căutare nelimitat</string>
|
<string name="unlimited_search_history">Istoric de căutare nelimitat</string>
|
||||||
<string name="duration">Durată</string>
|
<string name="duration">Durată</string>
|
||||||
<string name="duration_reversed">Durată (inversată)</string>
|
<string name="duration_reversed">Durată (inversată)</string>
|
||||||
|
<string name="shorts_notifications">Notificări pentru Shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -431,4 +431,5 @@
|
|||||||
<string name="unlimited_search_history">Неограниченная история поиска</string>
|
<string name="unlimited_search_history">Неограниченная история поиска</string>
|
||||||
<string name="duration_reversed">Продолжительность (обратная)</string>
|
<string name="duration_reversed">Продолжительность (обратная)</string>
|
||||||
<string name="duration">Продолжительность</string>
|
<string name="duration">Продолжительность</string>
|
||||||
|
<string name="shorts_notifications">Уведомления для shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -423,4 +423,9 @@
|
|||||||
<string name="show_stream_thumbnails_summary">නව ප්රවාහවල සිඟිති රූ පෙන්වන්න. මෙය සබල කිරීමෙන් අමතර Data වැය වේ.</string>
|
<string name="show_stream_thumbnails_summary">නව ප්රවාහවල සිඟිති රූ පෙන්වන්න. මෙය සබල කිරීමෙන් අමතර Data වැය වේ.</string>
|
||||||
<string name="fullscreen_gestures">පූර්ණ තිර ඇතුළු වන්න / පිටවන්න අභිනයන්</string>
|
<string name="fullscreen_gestures">පූර්ණ තිර ඇතුළු වන්න / පිටවන්න අභිනයන්</string>
|
||||||
<string name="unlimited_search_history">අසීමිත සෙවුම් ඉතිහාසය</string>
|
<string name="unlimited_search_history">අසීමිත සෙවුම් ඉතිහාසය</string>
|
||||||
|
<string name="playlist_name_az">වාදන ලැයිස්තු නම (A-Z)</string>
|
||||||
|
<string name="playlist_name_za">වාදන ලැයිස්තු නම (Z-A)</string>
|
||||||
|
<string name="duration">කාල සීමාව</string>
|
||||||
|
<string name="duration_reversed">කාල සීමාව (ප්රතිලෝම)</string>
|
||||||
|
<string name="shorts_notifications">Shorts සඳහා දැනුම්දීම්</string>
|
||||||
</resources>
|
</resources>
|
@ -57,7 +57,7 @@
|
|||||||
<string name="addToPlaylist">Додати в добірку</string>
|
<string name="addToPlaylist">Додати в добірку</string>
|
||||||
<string name="success">Готово.</string>
|
<string name="success">Готово.</string>
|
||||||
<string name="fail">Невдача :(</string>
|
<string name="fail">Невдача :(</string>
|
||||||
<string name="about">Про</string>
|
<string name="about">Про LibreTube</string>
|
||||||
<string name="changeLanguage">Мова</string>
|
<string name="changeLanguage">Мова</string>
|
||||||
<string name="systemLanguage">Системна</string>
|
<string name="systemLanguage">Системна</string>
|
||||||
<string name="systemDefault">Системна</string>
|
<string name="systemDefault">Системна</string>
|
||||||
@ -103,7 +103,7 @@
|
|||||||
<string name="color_purple">Приємний фіолетовий</string>
|
<string name="color_purple">Приємний фіолетовий</string>
|
||||||
<string name="material_you">Material You</string>
|
<string name="material_you">Material You</string>
|
||||||
<string name="sponsorblock_notifications">Сповіщення</string>
|
<string name="sponsorblock_notifications">Сповіщення</string>
|
||||||
<string name="enabled">Увімкнено</string>
|
<string name="enabled">Ввімкнено</string>
|
||||||
<string name="disabled">Вимкнено</string>
|
<string name="disabled">Вимкнено</string>
|
||||||
<string name="shareTo">Поділитися посиланням з</string>
|
<string name="shareTo">Поділитися посиланням з</string>
|
||||||
<string name="update_available">Версія %1$s доступна</string>
|
<string name="update_available">Версія %1$s доступна</string>
|
||||||
@ -146,7 +146,7 @@
|
|||||||
<string name="video">Відео</string>
|
<string name="video">Відео</string>
|
||||||
<string name="player_autoplay">Автоматичне відтворення</string>
|
<string name="player_autoplay">Автоматичне відтворення</string>
|
||||||
<string name="downloading">Завантаження…</string>
|
<string name="downloading">Завантаження…</string>
|
||||||
<string name="turnInternetOn">Будь ласка, увімкніть Wi-Fi або мобільний дані для підключення до Інтернету.</string>
|
<string name="turnInternetOn">Будь ласка, ввімкніть Wi-Fi або мобільний дані для підключення до Інтернету.</string>
|
||||||
<string name="open">Відкрити…</string>
|
<string name="open">Відкрити…</string>
|
||||||
<string name="reset">Відновити стандартні налаштування</string>
|
<string name="reset">Відновити стандартні налаштування</string>
|
||||||
<string name="reset_message">Стерти всі налаштування і вийти з облікового запису\?</string>
|
<string name="reset_message">Стерти всі налаштування і вийти з облікового запису\?</string>
|
||||||
@ -173,8 +173,8 @@
|
|||||||
<string name="portrait">Портретна</string>
|
<string name="portrait">Портретна</string>
|
||||||
<string name="instance_name">Назва екземпляра</string>
|
<string name="instance_name">Назва екземпляра</string>
|
||||||
<string name="playerVideoFormat">Формат відео для програвача</string>
|
<string name="playerVideoFormat">Формат відео для програвача</string>
|
||||||
<string name="auth_instance">Сервер аутентифікації</string>
|
<string name="auth_instance">Сервер автентифікації</string>
|
||||||
<string name="auth_instance_summary">Використовувати інший сервер для аутентифікації.</string>
|
<string name="auth_instance_summary">Використовувати інший сервер для автентифікації.</string>
|
||||||
<string name="aspect_ratio">Співвідношення сторін відео</string>
|
<string name="aspect_ratio">Співвідношення сторін відео</string>
|
||||||
<string name="auto_rotation">Автоповорот</string>
|
<string name="auto_rotation">Автоповорот</string>
|
||||||
<string name="chapters">Епізоди</string>
|
<string name="chapters">Епізоди</string>
|
||||||
@ -213,7 +213,7 @@
|
|||||||
<string name="required_network">Необхідне з\'єднання</string>
|
<string name="required_network">Необхідне з\'єднання</string>
|
||||||
<string name="network_metered">Лімітоване</string>
|
<string name="network_metered">Лімітоване</string>
|
||||||
<string name="repeat_mode_current">Поточний</string>
|
<string name="repeat_mode_current">Поточний</string>
|
||||||
<string name="picture_in_picture">Зображення в зображенні</string>
|
<string name="picture_in_picture">Картинка в картинці</string>
|
||||||
<string name="new_videos_badge_summary">Показувати значок із кількістю нових відео, якщо такі є.</string>
|
<string name="new_videos_badge_summary">Показувати значок із кількістю нових відео, якщо такі є.</string>
|
||||||
<string name="repeat_mode_none">Немає</string>
|
<string name="repeat_mode_none">Немає</string>
|
||||||
<string name="sb_skip_manual">Пропустити вручну</string>
|
<string name="sb_skip_manual">Пропустити вручну</string>
|
||||||
@ -330,7 +330,7 @@
|
|||||||
<string name="swipe_controls_summary">Для регулювання яскравості та гучності використовувати жест посування.</string>
|
<string name="swipe_controls_summary">Для регулювання яскравості та гучності використовувати жест посування.</string>
|
||||||
<string name="volume">Гучність</string>
|
<string name="volume">Гучність</string>
|
||||||
<string name="defaults">Типові</string>
|
<string name="defaults">Типові</string>
|
||||||
<string name="pop_up">Спливне вікно</string>
|
<string name="pop_up">Спливаюче вікно</string>
|
||||||
<string name="double_tap_seek">Двічі торкніться, щоб шукати</string>
|
<string name="double_tap_seek">Двічі торкніться, щоб шукати</string>
|
||||||
<string name="double_tap_seek_summary">Двічі торкніться ліворуч або праворуч, щоб перемотати назад або вперед.</string>
|
<string name="double_tap_seek_summary">Двічі торкніться ліворуч або праворуч, щоб перемотати назад або вперед.</string>
|
||||||
<string name="no_comments_available">До цього відео немає коментарів.</string>
|
<string name="no_comments_available">До цього відео немає коментарів.</string>
|
||||||
@ -410,7 +410,7 @@
|
|||||||
<string name="uploaderAndVideoCount">%1$s • %2$d відео</string>
|
<string name="uploaderAndVideoCount">%1$s • %2$d відео</string>
|
||||||
<string name="subscriberAndVideoCounts">%1$s підписників • %2$d відео</string>
|
<string name="subscriberAndVideoCounts">%1$s підписників • %2$d відео</string>
|
||||||
<string name="disable_proxy">Вимкнути транспортний проксі</string>
|
<string name="disable_proxy">Вимкнути транспортний проксі</string>
|
||||||
<string name="disable_proxy_summary">Завантажуйте відео й зображення безпосередньо з серверів YouTube. Увімкніть цю опцію, якщо ви все одно використовуєте VPN! Зауважте, що це може не спрацювати з матеріалами з YT music.</string>
|
<string name="disable_proxy_summary">Завантажуйте відео й зображення безпосередньо з серверів YouTube. Ввімкніть цю опцію, якщо ви все одно використовуєте VPN! Зауважте, що це може не спрацювати з матеріалами з YT music.</string>
|
||||||
<string name="auto_fullscreen_shorts">Автоматичний повноекранний режим для коротких відео</string>
|
<string name="auto_fullscreen_shorts">Автоматичний повноекранний режим для коротких відео</string>
|
||||||
<string name="new_group">Нова</string>
|
<string name="new_group">Нова</string>
|
||||||
<string name="edit_group">Редагувати групу</string>
|
<string name="edit_group">Редагувати групу</string>
|
||||||
@ -426,9 +426,10 @@
|
|||||||
<item quantity="many">%d нових трансляцій</item>
|
<item quantity="many">%d нових трансляцій</item>
|
||||||
<item quantity="other">%d нових трансляцій</item>
|
<item quantity="other">%d нових трансляцій</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="show_stream_thumbnails_summary">Показувати мініатюри нових трансляцій. Увімкнення цієї опції споживає додаткові дані.</string>
|
<string name="show_stream_thumbnails_summary">Показувати мініатюри нових трансляцій. Ввімкнення цієї опції споживає додаткові дані.</string>
|
||||||
<string name="show_stream_thumbnails">Показувати мініатюри трансляцій</string>
|
<string name="show_stream_thumbnails">Показувати мініатюри трансляцій</string>
|
||||||
<string name="unlimited_search_history">Необмежена історія запитів</string>
|
<string name="unlimited_search_history">Необмежена історія запитів</string>
|
||||||
<string name="duration">Тривалість</string>
|
<string name="duration">Тривалість</string>
|
||||||
<string name="duration_reversed">Тривалість (у зворотному порядку)</string>
|
<string name="duration_reversed">Тривалість (у зворотному порядку)</string>
|
||||||
|
<string name="shorts_notifications">Сповіщення для shorts</string>
|
||||||
</resources>
|
</resources>
|
@ -422,4 +422,5 @@
|
|||||||
<string name="unlimited_search_history">无限搜索历史条目</string>
|
<string name="unlimited_search_history">无限搜索历史条目</string>
|
||||||
<string name="duration">时长</string>
|
<string name="duration">时长</string>
|
||||||
<string name="duration_reversed">时长(倒序)</string>
|
<string name="duration_reversed">时长(倒序)</string>
|
||||||
|
<string name="shorts_notifications">短视频通知</string>
|
||||||
</resources>
|
</resources>
|
@ -188,8 +188,8 @@
|
|||||||
<string name="background_channel_description">在通知欄顯示附有按鈕的音訊播放器。</string>
|
<string name="background_channel_description">在通知欄顯示附有按鈕的音訊播放器。</string>
|
||||||
<string name="history_empty">尚無歷史紀錄。</string>
|
<string name="history_empty">尚無歷史紀錄。</string>
|
||||||
<string name="notifications">通知</string>
|
<string name="notifications">通知</string>
|
||||||
<string name="notify_new_streams">新串流通知</string>
|
<string name="notify_new_streams">顯示新串流通知</string>
|
||||||
<string name="notify_new_streams_summary">您跟隨的創作者最新串流的通知。</string>
|
<string name="notify_new_streams_summary">顯示您跟隨的創作者最新串流的通知。</string>
|
||||||
<string name="wifi">Wi-Fi</string>
|
<string name="wifi">Wi-Fi</string>
|
||||||
<string name="pop_up">彈出</string>
|
<string name="pop_up">彈出</string>
|
||||||
<string name="no_comments_available">此視頻沒有評論。</string>
|
<string name="no_comments_available">此視頻沒有評論。</string>
|
||||||
@ -213,8 +213,8 @@
|
|||||||
<string name="time">時長</string>
|
<string name="time">時長</string>
|
||||||
<string name="start_time">開始時間</string>
|
<string name="start_time">開始時間</string>
|
||||||
<string name="end_time">結束時間</string>
|
<string name="end_time">結束時間</string>
|
||||||
<string name="notification_time">通知時長</string>
|
<string name="notification_time">限制通知時間</string>
|
||||||
<string name="notification_time_summary">通知顯示的時長。</string>
|
<string name="notification_time_summary">限制串流通知顯示的時間。</string>
|
||||||
<string name="download_completed">下載完成</string>
|
<string name="download_completed">下載完成</string>
|
||||||
<string name="failed_fetching_instances">無法取得可用實例。</string>
|
<string name="failed_fetching_instances">無法取得可用實例。</string>
|
||||||
<string name="play_next">播放下一部</string>
|
<string name="play_next">播放下一部</string>
|
||||||
@ -401,4 +401,28 @@
|
|||||||
<string name="lbry_hls_summary">如果可用,請使用 LBRY HLS 進行流式傳輸。</string>
|
<string name="lbry_hls_summary">如果可用,請使用 LBRY HLS 進行流式傳輸。</string>
|
||||||
<string name="lbry_hls">LBRY HLS</string>
|
<string name="lbry_hls">LBRY HLS</string>
|
||||||
<string name="replies">回复</string>
|
<string name="replies">回复</string>
|
||||||
|
<string name="playlist_name_az">播放清單名稱 (A-Z)</string>
|
||||||
|
<string name="playlist_name_za">播放清單名稱 (Z-A)</string>
|
||||||
|
<string name="duration">持續時間</string>
|
||||||
|
<string name="duration_reversed">持續時間(反轉)</string>
|
||||||
|
<string name="unlimited_search_history">無限制搜尋歷史紀錄</string>
|
||||||
|
<string name="fullscreen_gestures">進入/退出全螢幕手勢</string>
|
||||||
|
<string name="show_stream_thumbnails_summary">顯示新串流的縮圖。啟用此選項會消耗更多流量。</string>
|
||||||
|
<string name="stats_for_nerds">詳細統計資料</string>
|
||||||
|
<string name="auto_fullscreen_shorts">短片自動全螢幕</string>
|
||||||
|
<plurals name="channel_new_streams">
|
||||||
|
<item quantity="other">%d 個新串流</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="go_to_video">前往影片</string>
|
||||||
|
<string name="disable_proxy">停用 Piped 代理伺服器</string>
|
||||||
|
<string name="channel_groups">頻道群組</string>
|
||||||
|
<string name="new_group">新</string>
|
||||||
|
<string name="group_name">群組名稱</string>
|
||||||
|
<string name="edit_group">編輯群組</string>
|
||||||
|
<string name="shorts_notifications">短片通知</string>
|
||||||
|
<string name="show_stream_thumbnails">顯示串流縮圖</string>
|
||||||
|
<string name="disable_proxy_summary">直接從 YouTube 的伺服器載入影片與圖片。僅在您使用 VPN 時才啟用此選項!注意,這可能對來自 YouTube 音樂的內容無效。</string>
|
||||||
|
<string name="video_id">視訊 ID</string>
|
||||||
|
<string name="play_automatically">自動播放</string>
|
||||||
|
<string name="play_automatically_summary">選取時自動開始播放影片</string>
|
||||||
</resources>
|
</resources>
|
@ -11,7 +11,7 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
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-gradle-plugin:$kotlin_version"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$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 for this project: "official" or "obsolete":
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
android.defaults.buildfeatures.buildconfig=true
|
||||||
|
android.nonTransitiveRClass=true
|
||||||
|
android.nonFinalResIds=true
|
@ -1,6 +1,6 @@
|
|||||||
[versions]
|
[versions]
|
||||||
appcompat = "1.6.1"
|
appcompat = "1.6.1"
|
||||||
core = "1.10.0"
|
core = "1.10.1"
|
||||||
lifecycle = "2.6.1"
|
lifecycle = "2.6.1"
|
||||||
constraintlayout = "2.1.4"
|
constraintlayout = "2.1.4"
|
||||||
material = "1.9.0"
|
material = "1.9.0"
|
||||||
@ -18,7 +18,7 @@ cronetOkHttp = "0.1.0"
|
|||||||
coil = "2.3.0"
|
coil = "2.3.0"
|
||||||
leakcanary = "2.10"
|
leakcanary = "2.10"
|
||||||
room = "2.5.1"
|
room = "2.5.1"
|
||||||
kotlinxSerialization = "1.5.0"
|
kotlinxSerialization = "1.5.1"
|
||||||
kotlinxDatetime = "0.4.0"
|
kotlinxDatetime = "0.4.0"
|
||||||
kotlinxRetrofit = "1.0.0"
|
kotlinxRetrofit = "1.0.0"
|
||||||
|
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
networkTimeout=10000
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
11
gradlew
vendored
11
gradlew
vendored
@ -85,9 +85,6 @@ done
|
|||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
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.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|
||||||
@ -144,7 +141,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
# 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 ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
@ -152,7 +149,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
# 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" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then
|
|||||||
done
|
done
|
||||||
fi
|
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;
|
# Collect all arguments for the java command;
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
Loading…
Reference in New Issue
Block a user