diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 528518992..19925de3f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,7 +13,7 @@ android { defaultConfig { applicationId = "com.github.libretube" - minSdk = 21 + minSdk = 26 targetSdk = 34 versionCode = 59 versionName = "0.27.0" diff --git a/app/src/main/java/com/github/libretube/compat/PictureInPictureCompat.kt b/app/src/main/java/com/github/libretube/compat/PictureInPictureCompat.kt index 10f2d6f7e..43b5043d7 100644 --- a/app/src/main/java/com/github/libretube/compat/PictureInPictureCompat.kt +++ b/app/src/main/java/com/github/libretube/compat/PictureInPictureCompat.kt @@ -3,17 +3,13 @@ package com.github.libretube.compat import android.app.Activity import android.content.Context import android.content.pm.PackageManager -import android.os.Build object PictureInPictureCompat { - fun isPictureInPictureAvailable(context: Context): Boolean { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - context.packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) - } - fun isInPictureInPictureMode(activity: Activity): Boolean { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && activity.isInPictureInPictureMode - } + fun isPictureInPictureAvailable(context: Context) = + context.packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) + + fun isInPictureInPictureMode(activity: Activity) = activity.isInPictureInPictureMode fun setPictureInPictureParams(activity: Activity, params: PictureInPictureParamsCompat) { if (isPictureInPictureAvailable(activity)) { diff --git a/app/src/main/java/com/github/libretube/extensions/FormatShort.kt b/app/src/main/java/com/github/libretube/extensions/FormatShort.kt index 873656f8b..5a2de2cb8 100644 --- a/app/src/main/java/com/github/libretube/extensions/FormatShort.kt +++ b/app/src/main/java/com/github/libretube/extensions/FormatShort.kt @@ -1,22 +1,8 @@ package com.github.libretube.extensions import android.icu.text.CompactDecimalFormat -import android.os.Build import com.github.libretube.helpers.LocaleHelper -import kotlin.math.pow -fun Long?.formatShort(): String { - val value = this ?: 0 - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - CompactDecimalFormat - .getInstance(LocaleHelper.getAppLocale(), CompactDecimalFormat.CompactStyle.SHORT) - .format(value) - } else { - val units = arrayOf("", "K", "M", "B", "T") - for (i in units.size downTo 1) { - val step = 1000.0.pow(i.toDouble()) - if (value > step) return "%3.0f%s".format(value / step, units[i]).trim() - } - value.toString() - } -} +fun Long?.formatShort(): String = CompactDecimalFormat + .getInstance(LocaleHelper.getAppLocale(), CompactDecimalFormat.CompactStyle.SHORT) + .format(this ?: 0) diff --git a/app/src/main/java/com/github/libretube/helpers/DisplayHelper.kt b/app/src/main/java/com/github/libretube/helpers/DisplayHelper.kt index b632ce8dc..91f6f09ae 100644 --- a/app/src/main/java/com/github/libretube/helpers/DisplayHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/DisplayHelper.kt @@ -1,7 +1,6 @@ package com.github.libretube.helpers import android.content.Context -import android.os.Build import androidx.core.content.ContextCompat object DisplayHelper { @@ -9,17 +8,5 @@ object DisplayHelper { * Detect whether the device supports HDR as the ExoPlayer doesn't handle it properly * Returns false below SDK 24 */ - fun supportsHdr(context: Context): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val display = ContextCompat.getDisplayOrDefault(context) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - display.isHdr - } else { - @Suppress("DEPRECATION") - display.hdrCapabilities?.supportedHdrTypes?.isNotEmpty() ?: false - } - } else { - false - } - } + fun supportsHdr(context: Context) = ContextCompat.getDisplayOrDefault(context).isHdr } 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 e492f1298..5d87ea13e 100644 --- a/app/src/main/java/com/github/libretube/helpers/DownloadHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/DownloadHelper.kt @@ -2,7 +2,6 @@ package com.github.libretube.helpers import android.content.Context import android.content.Intent -import android.os.Build import androidx.core.content.ContextCompat import androidx.core.net.toUri import androidx.core.os.bundleOf @@ -40,15 +39,12 @@ object DownloadHelper { private const val VIDEO_MIMETYPE = "video/*" fun getDownloadDir(context: Context, path: String): Path { - val storageDir = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - context.filesDir - } else { + val storageDir = try { context.getExternalFilesDir(null)!! } catch (e: Exception) { context.filesDir } - } return (storageDir.toPath() / path).createDirectories() } diff --git a/app/src/main/java/com/github/libretube/helpers/LocaleHelper.kt b/app/src/main/java/com/github/libretube/helpers/LocaleHelper.kt index 8cfc9b048..8f30500fd 100644 --- a/app/src/main/java/com/github/libretube/helpers/LocaleHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/LocaleHelper.kt @@ -2,7 +2,6 @@ package com.github.libretube.helpers import android.content.Context import android.content.res.Configuration -import android.os.Build import android.telephony.TelephonyManager import androidx.core.content.getSystemService import androidx.core.os.ConfigurationCompat @@ -29,7 +28,7 @@ object LocaleHelper { fun updateLanguage(context: Context) { val locale = getAppLocale() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) updateResources(context, locale) + updateResources(context, locale) updateResourcesLegacy(context, locale) } 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 9c90864d8..94c8cb00f 100644 --- a/app/src/main/java/com/github/libretube/helpers/NetworkHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/NetworkHelper.kt @@ -3,29 +3,20 @@ package com.github.libretube.helpers import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities -import android.os.Build import androidx.core.content.getSystemService 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 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val activeNetwork = connectivityManager.activeNetwork - val caps = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false - return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) || - caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN) - } else { - // activeNetworkInfo might return null instead of the VPN, so better check it explicitly - val networkInfo = connectivityManager.activeNetworkInfo - ?: connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN) - return networkInfo?.isConnected == true - } + val activeNetwork = connectivityManager.activeNetwork + val caps = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false + return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) || + caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN) } /** 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 2779429a3..f5024bdf4 100644 --- a/app/src/main/java/com/github/libretube/helpers/ThemeHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/ThemeHelper.kt @@ -6,7 +6,6 @@ import android.content.Context import android.content.pm.PackageManager import android.content.res.Configuration import android.graphics.Color -import android.os.Build import android.text.Spanned import android.view.Window import androidx.annotation.ColorInt @@ -35,12 +34,7 @@ object ThemeHelper { * Set the background color of the status bar */ private fun setStatusBarColor(context: Context, window: Window) { - window.statusBarColor = - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M && !isDarkMode(context)) { - getThemeColor(context, com.google.android.material.R.attr.colorOnBackground) - } else { - getThemeColor(context, android.R.attr.colorBackground) - } + window.statusBarColor = getThemeColor(context, android.R.attr.colorBackground) WindowCompat.getInsetsController(window, window.decorView) .isAppearanceLightStatusBars = !isDarkMode(context) } @@ -54,11 +48,7 @@ object ThemeHelper { @ColorInt bottomNavColor: Int? ) { window.navigationBarColor = - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M && !isDarkMode(context)) { - getThemeColor(context, com.google.android.material.R.attr.colorOnBackground) - } else { - bottomNavColor ?: getThemeColor(context, android.R.attr.colorBackground) - } + bottomNavColor ?: getThemeColor(context, android.R.attr.colorBackground) } /** diff --git a/app/src/main/java/com/github/libretube/ui/base/BaseActivity.kt b/app/src/main/java/com/github/libretube/ui/base/BaseActivity.kt index 31f3ea2d2..96d2e49f4 100644 --- a/app/src/main/java/com/github/libretube/ui/base/BaseActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/base/BaseActivity.kt @@ -1,7 +1,6 @@ package com.github.libretube.ui.base import android.content.pm.ActivityInfo -import android.os.Build import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.github.libretube.R @@ -40,11 +39,6 @@ open class BaseActivity : AppCompatActivity() { ThemeHelper.updateTheme(this) if (isDialogActivity) ThemeHelper.applyDialogActivityTheme(this) - // Set the navigation and statusBar color if SDK < 23 - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - ThemeHelper.setSystemBarColors(this, window) - } - // set the apps language LocaleHelper.updateLanguage(this) diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 3e152fbb6..f9cc2771c 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -733,27 +733,23 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions { DownloadHelper.startDownloadDialog(requireContext(), childFragmentManager, videoId) } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - binding.relPlayerScreenshot.setOnClickListener { - if (!this::streams.isInitialized) return@setOnClickListener - val surfaceView = - binding.player.videoSurfaceView as? SurfaceView ?: return@setOnClickListener + binding.relPlayerScreenshot.setOnClickListener { + if (!this::streams.isInitialized) return@setOnClickListener + val surfaceView = + binding.player.videoSurfaceView as? SurfaceView ?: return@setOnClickListener - val bmp = Bitmap.createBitmap( - surfaceView.width, - surfaceView.height, - Bitmap.Config.ARGB_8888 - ) + val bmp = Bitmap.createBitmap( + surfaceView.width, + surfaceView.height, + Bitmap.Config.ARGB_8888 + ) - PixelCopy.request(surfaceView, bmp, { _ -> - screenshotBitmap = bmp - val currentPosition = - playerController.currentPosition.toFloat() / 1000 - openScreenshotFile.launch("${streams.title}-${currentPosition}.png") - }, Handler(Looper.getMainLooper())) - } - } else { - binding.relPlayerScreenshot.isGone = true + PixelCopy.request(surfaceView, bmp, { _ -> + screenshotBitmap = bmp + val currentPosition = + playerController.currentPosition.toFloat() / 1000 + openScreenshotFile.launch("${streams.title}-${currentPosition}.png") + }, Handler(Looper.getMainLooper())) } binding.playerChannel.setOnClickListener { diff --git a/app/src/main/java/com/github/libretube/ui/views/DescriptionLayout.kt b/app/src/main/java/com/github/libretube/ui/views/DescriptionLayout.kt index aa9f9a8c2..c7e054932 100644 --- a/app/src/main/java/com/github/libretube/ui/views/DescriptionLayout.kt +++ b/app/src/main/java/com/github/libretube/ui/views/DescriptionLayout.kt @@ -68,7 +68,7 @@ class DescriptionLayout( this.streams = streams val views = streams.views.formatShort() - val date = TextUtils.formatRelativeDate(context, streams.uploaded ?: -1L) + val date = TextUtils.formatRelativeDate(streams.uploaded ?: -1L) binding.run { playerViewsInfo.text = context.getString(R.string.normal_views, views, TextUtils.SEPARATOR + date) @@ -135,7 +135,7 @@ class DescriptionLayout( val isNewStateExpanded = binding.descLinLayout.isGone if (!isNewStateExpanded) { // show a short version of the view count and date - val formattedDate = TextUtils.formatRelativeDate(context, streams.uploaded ?: -1L) + val formattedDate = TextUtils.formatRelativeDate(streams.uploaded ?: -1L) binding.playerViewsInfo.text = context.getString(R.string.normal_views, streams.views.formatShort(), TextUtils.SEPARATOR + formattedDate) // limit the title height to two lines diff --git a/app/src/main/java/com/github/libretube/util/TextUtils.kt b/app/src/main/java/com/github/libretube/util/TextUtils.kt index 00466b51f..a9f62f7c9 100644 --- a/app/src/main/java/com/github/libretube/util/TextUtils.kt +++ b/app/src/main/java/com/github/libretube/util/TextUtils.kt @@ -3,7 +3,6 @@ package com.github.libretube.util import android.content.Context import android.icu.text.RelativeDateTimeFormatter import android.net.Uri -import android.os.Build import android.text.format.DateUtils import androidx.core.text.isDigitsOnly import com.github.libretube.BuildConfig @@ -111,7 +110,7 @@ object TextUtils { else -> null } - fun formatRelativeDate(context: Context, unixTime: Long): CharSequence { + fun formatRelativeDate(unixTime: Long): CharSequence { val date = LocalDateTime.ofInstant(Instant.ofEpochMilli(unixTime), ZoneId.systemDefault()) val now = LocalDateTime.now() val months = date.until(now, ChronoUnit.MONTHS) @@ -119,22 +118,13 @@ object TextUtils { return if (months > 0) { val years = months / 12 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val (timeFormat, time) = if (years > 0) { - RelativeDateTimeFormatter.RelativeUnit.YEARS to years - } else { - RelativeDateTimeFormatter.RelativeUnit.MONTHS to months - } - RelativeDateTimeFormatter.getInstance() - .format(time.toDouble(), RelativeDateTimeFormatter.Direction.LAST, timeFormat) + val (timeFormat, time) = if (years > 0) { + RelativeDateTimeFormatter.RelativeUnit.YEARS to years } else { - val (timeAgoRes, time) = if (years > 0) { - R.plurals.years_ago to years - } else { - R.plurals.months_ago to months - } - context.resources.getQuantityString(timeAgoRes, time.toInt(), time) + RelativeDateTimeFormatter.RelativeUnit.MONTHS to months } + RelativeDateTimeFormatter.getInstance() + .format(time.toDouble(), RelativeDateTimeFormatter.Direction.LAST, timeFormat) } else { val weeks = date.until(now, ChronoUnit.WEEKS) val minResolution = if (weeks > 0) DateUtils.WEEK_IN_MILLIS else 0L @@ -161,7 +151,7 @@ object TextUtils { context.getString(R.string.view_count, it) } val uploadDate = uploaded.takeIf { it > 0 }?.let { - formatRelativeDate(context, it) + formatRelativeDate(it) } return listOfNotNull(uploader, viewsString, uploadDate).joinToString(SEPARATOR) }