AquaStream/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt

356 lines
12 KiB
Kotlin
Raw Normal View History

package com.lagradost.cloudstream3.utils
2021-05-12 21:51:02 +00:00
2021-05-20 21:25:41 +00:00
import android.Manifest
2021-06-15 23:25:58 +00:00
import android.annotation.SuppressLint
2021-05-12 21:51:02 +00:00
import android.app.Activity
2021-06-10 23:00:22 +00:00
import android.app.AppOpsManager
2021-05-28 13:38:06 +00:00
import android.content.Context
2021-05-20 21:25:41 +00:00
import android.content.pm.PackageManager
2021-05-15 23:37:42 +00:00
import android.content.res.Resources
2021-06-14 00:00:29 +00:00
import android.graphics.Color
2021-05-28 13:38:06 +00:00
import android.os.Build
2021-09-20 21:11:36 +00:00
import android.os.Bundle
2021-06-15 23:25:58 +00:00
import android.view.Gravity
import android.view.MenuItem
2021-05-12 21:51:02 +00:00
import android.view.View
2021-06-06 18:06:01 +00:00
import android.view.WindowManager
2021-06-10 23:00:22 +00:00
import android.view.inputmethod.InputMethodManager
2021-08-19 20:05:18 +00:00
import android.widget.ImageView
2021-09-20 21:11:36 +00:00
import androidx.annotation.*
2021-06-15 23:25:58 +00:00
import androidx.appcompat.view.ContextThemeWrapper
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
2021-05-20 21:25:41 +00:00
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
2021-07-19 13:19:47 +00:00
import androidx.core.graphics.alpha
import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
import androidx.fragment.app.Fragment
2021-06-06 18:06:01 +00:00
import androidx.fragment.app.FragmentActivity
2021-09-20 21:11:36 +00:00
import androidx.navigation.fragment.NavHostFragment
2021-05-15 23:37:42 +00:00
import androidx.preference.PreferenceManager
2021-08-19 20:05:18 +00:00
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.lagradost.cloudstream3.R
2021-09-01 13:18:41 +00:00
import com.lagradost.cloudstream3.mvvm.logError
2021-06-14 00:00:29 +00:00
import kotlin.math.roundToInt
2021-05-12 21:51:02 +00:00
object UIHelper {
2021-05-15 23:37:42 +00:00
val Int.toPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Float.toPx: Float get() = (this * Resources.getSystem().displayMetrics.density)
val Int.toDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()
val Float.toDp: Float get() = (this / Resources.getSystem().displayMetrics.density)
2021-05-20 21:25:41 +00:00
fun Activity.checkWrite(): Boolean {
2021-07-24 15:13:21 +00:00
return (ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
2021-05-20 21:25:41 +00:00
== PackageManager.PERMISSION_GRANTED)
}
fun Activity.requestRW() {
2021-07-24 15:13:21 +00:00
ActivityCompat.requestPermissions(
this,
2021-05-20 21:25:41 +00:00
arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
),
2021-07-24 15:13:21 +00:00
1337
)
2021-05-20 21:25:41 +00:00
}
fun Fragment.hideKeyboard() {
2021-08-04 13:30:34 +00:00
activity?.window?.decorView?.clearFocus()
view.let {
if (it != null) {
activity?.hideKeyboard(it)
}
}
}
2021-09-20 21:11:36 +00:00
fun Activity?.navigate(@IdRes navigation : Int, arguments : Bundle? = null) {
if(this is FragmentActivity) {
(supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment?)?.navController?.navigate(
navigation, arguments
)
}
}
2021-07-19 13:19:47 +00:00
@ColorInt
fun Context.getResourceColor(@AttrRes resource: Int, alphaFactor: Float = 1f): Int {
val typedArray = obtainStyledAttributes(intArrayOf(resource))
val color = typedArray.getColor(0, 0)
typedArray.recycle()
if (alphaFactor < 1f) {
val alpha = (color.alpha * alphaFactor).roundToInt()
return Color.argb(alpha, color.red, color.green, color.blue)
}
return color
}
2021-08-19 20:05:18 +00:00
fun ImageView?.setImage(url : String?) {
if(this == null || url.isNullOrBlank()) return
try {
GlideApp.with(this.context)
2021-08-19 20:05:18 +00:00
.load(GlideUrl(url))
.into(this)
} catch (e : Exception) {
2021-09-01 13:18:41 +00:00
logError(e)
2021-08-19 20:05:18 +00:00
}
}
2021-06-14 00:00:29 +00:00
fun adjustAlpha(@ColorInt color: Int, factor: Float): Int {
val alpha = (Color.alpha(color) * factor).roundToInt()
val red = Color.red(color)
val green = Color.green(color)
val blue = Color.blue(color)
return Color.argb(alpha, red, green, blue)
}
fun Context.colorFromAttribute(attribute: Int): Int {
val attributes = obtainStyledAttributes(intArrayOf(attribute))
val color = attributes.getColor(0, 0)
attributes.recycle()
return color
}
2021-06-06 18:06:01 +00:00
fun Activity.hideSystemUI() {
// Enables regular immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
2021-06-10 19:43:05 +00:00
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
2021-07-24 15:13:21 +00:00
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
2021-06-06 18:06:01 +00:00
// or View.SYSTEM_UI_FLAG_LOW_PROFILE
)
// window.addFlags(View.KEEP_SCREEN_ON)
}
2021-07-24 15:13:21 +00:00
2021-06-10 18:21:42 +00:00
fun FragmentActivity.popCurrentPage() {
2021-09-20 21:11:36 +00:00
this.onBackPressed()
/*val currentFragment = supportFragmentManager.fragments.lastOrNull {
2021-06-10 18:21:42 +00:00
it.isVisible
} ?: return
2021-06-06 18:06:01 +00:00
2021-06-10 18:21:42 +00:00
supportFragmentManager.beginTransaction()
.setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim,
R.anim.pop_enter,
R.anim.pop_exit
)
.remove(currentFragment)
2021-09-20 21:11:36 +00:00
.commitAllowingStateLoss()*/
2021-06-10 18:21:42 +00:00
}
/*
2021-06-06 18:06:01 +00:00
fun FragmentActivity.popCurrentPage(isInPlayer: Boolean, isInExpandedView: Boolean, isInResults: Boolean) {
val currentFragment = supportFragmentManager.fragments.lastOrNull {
it.isVisible
}
?: //this.onBackPressed()
return
/*
if (tvActivity == null) {
requestedOrientation = if (settingsManager?.getBoolean("force_landscape", false) == true) {
ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
} else {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
}*/
// No fucked animations leaving the player :)
when {
isInPlayer -> {
supportFragmentManager.beginTransaction()
//.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit)
.remove(currentFragment)
.commitAllowingStateLoss()
}
isInExpandedView && !isInResults -> {
supportFragmentManager.beginTransaction()
.setCustomAnimations(
R.anim.enter_anim,//R.anim.enter_from_right,
R.anim.exit_anim,//R.anim.exit_to_right,
R.anim.pop_enter,
R.anim.pop_exit
)
.remove(currentFragment)
.commitAllowingStateLoss()
}
else -> {
supportFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit)
.remove(currentFragment)
.commitAllowingStateLoss()
}
}
2021-06-10 18:21:42 +00:00
}*/
2021-06-06 18:06:01 +00:00
fun Context.getStatusBarHeight(): Int {
var result = 0
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
if (resourceId > 0) {
result = resources.getDimensionPixelSize(resourceId)
}
return result
}
fun Context.fixPaddingStatusbar(v: View) {
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
}
fun Context.getNavigationBarHeight(): Int {
var result = 0
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
if (resourceId > 0) {
result = resources.getDimensionPixelSize(resourceId)
}
return result
}
private fun Context.getGridFormat(): String {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
return settingsManager.getString(getString(R.string.grid_format_key), "grid")!!
}
fun Context.getGridFormatId(): Int {
return when (getGridFormat()) {
"list" -> R.layout.search_result_compact
"compact_list" -> R.layout.search_result_super_compact
else -> R.layout.search_result_grid
}
}
fun Context.getGridIsCompact(): Boolean {
return getGridFormat() != "grid"
}
2021-06-06 18:06:01 +00:00
fun Activity.changeStatusBarState(hide: Boolean): Int {
return if (hide) {
window?.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
0
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
this.getStatusBarHeight()
}
}
// Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
fun Activity.showSystemUI() {
2021-06-10 19:43:05 +00:00
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
) // or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
2021-06-06 18:06:01 +00:00
// window.clearFlags(View.KEEP_SCREEN_ON)
}
2021-06-10 23:00:22 +00:00
fun Context.shouldShowPIPMode(isInPlayer: Boolean): Boolean {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
return settingsManager?.getBoolean("pip_enabled", true) ?: true && isInPlayer
}
2021-08-19 20:05:18 +00:00
@RequiresApi(Build.VERSION_CODES.O)
2021-06-10 23:00:22 +00:00
fun Context.hasPIPPermission(): Boolean {
val appOps =
getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
return appOps.checkOpNoThrow(
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
android.os.Process.myUid(),
packageName
) == AppOpsManager.MODE_ALLOWED
}
fun Context.hideKeyboard(view: View) {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
2021-06-15 23:25:58 +00:00
2021-07-24 15:13:21 +00:00
/**id, icon, stringRes */
2021-06-15 23:25:58 +00:00
@SuppressLint("RestrictedApi")
2021-07-24 15:13:21 +00:00
fun View.popupMenu(
2021-06-15 23:25:58 +00:00
items: List<Triple<Int, Int, Int>>,
2021-07-24 15:13:21 +00:00
onMenuItemClick: MenuItem.() -> Unit,
2021-06-15 23:25:58 +00:00
): PopupMenu {
val ctw = ContextThemeWrapper(context, R.style.PopupMenu)
val popup = PopupMenu(ctw, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
items.forEach { (id, icon, stringRes) ->
popup.menu.add(0, id, 0, stringRes).setIcon(icon)
}
(popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
popup.setOnMenuItemClickListener {
it.onMenuItemClick()
true
}
popup.show()
return popup
}
2021-07-24 15:13:21 +00:00
/**id, stringRes */
@SuppressLint("RestrictedApi")
fun View.popupMenuNoIcons(
2021-06-15 23:25:58 +00:00
items: List<Pair<Int, Int>>,
2021-07-24 15:13:21 +00:00
onMenuItemClick: MenuItem.() -> Unit,
2021-06-15 23:25:58 +00:00
): PopupMenu {
val ctw = ContextThemeWrapper(context, R.style.PopupMenu)
val popup = PopupMenu(ctw, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
items.forEach { (id, stringRes) ->
popup.menu.add(0, id, 0, stringRes)
}
(popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
popup.setOnMenuItemClickListener {
it.onMenuItemClick()
true
}
popup.show()
return popup
}
2021-06-26 22:15:19 +00:00
2021-07-24 15:13:21 +00:00
/**id, string */
@SuppressLint("RestrictedApi")
2021-07-25 20:50:16 +00:00
fun View.popupMenuNoIconsAndNoStringRes(
2021-06-26 22:15:19 +00:00
items: List<Pair<Int, String>>,
2021-07-24 15:13:21 +00:00
onMenuItemClick: MenuItem.() -> Unit,
2021-06-26 22:15:19 +00:00
): PopupMenu {
val ctw = ContextThemeWrapper(context, R.style.PopupMenu)
val popup = PopupMenu(ctw, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
2021-07-24 15:13:21 +00:00
items.forEach { (id, string) ->
popup.menu.add(0, id, 0, string)
2021-06-26 22:15:19 +00:00
}
(popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
popup.setOnMenuItemClickListener {
it.onMenuItemClick()
true
}
popup.show()
return popup
}
2021-05-12 21:51:02 +00:00
}