224 lines
7.6 KiB
Kotlin

package com.tommasoberlose.anotherwidget.utils
import android.content.pm.PackageManager
import android.view.Gravity
import android.view.View
import android.view.ViewAnimationUtils
import android.widget.Toast
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Activity
import android.app.WallpaperManager
import android.content.*
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat
import android.content.res.Configuration
import android.provider.Settings
import android.util.Patterns
import java.security.NoSuchAlgorithmException
import kotlin.math.max
import android.content.Intent
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.util.DisplayMetrics
import android.util.TypedValue
import android.view.animation.Animation
import android.view.animation.Transformation
import android.widget.LinearLayout
import com.tommasoberlose.anotherwidget.R
import java.util.*
fun PackageManager.missingSystemFeature(name: String): Boolean = !hasSystemFeature(name)
fun Context.toast(message: String, long: Boolean = false) {
val toast = Toast.makeText(this, message, if (long) Toast.LENGTH_LONG else Toast.LENGTH_SHORT)
// toast.setGravity(Gravity.CENTER, 0, 0)
toast.show()
}
fun Int.toPixel(context: Context): Int = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), context.resources.displayMetrics).toInt()
fun Float.toPixel(context: Context): Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, context.resources.displayMetrics)
fun View.reveal(initialX: Int? = null, initialY: Int? = null) {
when (visibility) {
View.VISIBLE -> {
val anim = ViewAnimationUtils.createCircularReveal(this, initialX ?: this.measuredWidth / 2, initialY ?: this.measuredHeight / 2, max(width.toFloat(), height.toFloat()), 0f)
.apply {
duration = 200
}
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
visibility = View.GONE
super.onAnimationEnd(animation)
}
})
anim.start()
} else -> {
val anim = ViewAnimationUtils.createCircularReveal(this, initialX ?: this.measuredWidth / 2, initialY ?: this.measuredHeight / 2, 0f, max(width.toFloat(), height.toFloat()))
.apply {
duration = 200
}
visibility = View.VISIBLE
anim.start()
}
}
}
fun View.expand() {
if (visibility != View.VISIBLE) {
measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
val targetHeight = measuredHeight
layoutParams.height = 0
visibility = View.VISIBLE
val a = object : Animation() {
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
layoutParams.height = if (interpolatedTime == 1f)
LinearLayout.LayoutParams.WRAP_CONTENT
else
(targetHeight * interpolatedTime).toInt()
translationY = 0f
requestLayout()
}
override fun willChangeBounds(): Boolean {
return true
}
}
a.duration = 500L
startAnimation(a)
}
}
fun View.collapse() {
if (visibility != View.GONE) {
val initialHeight = measuredHeight
val a = object : Animation() {
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
if (interpolatedTime == 1f) {
visibility = View.GONE
} else {
layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
requestLayout()
}
}
override fun willChangeBounds(): Boolean {
return true
}
}
a.duration = 500L //(initialHeight / v.context.resources.displayMetrics.density).toLong()
startAnimation(a)
}
}
fun Context.openURI(url: String) {
try {
val builder: CustomTabsIntent.Builder = CustomTabsIntent.Builder()
builder.setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary))
val customTabsIntent: CustomTabsIntent = builder.build()
customTabsIntent.launchUrl(this, Uri.parse(url))
} catch (e: Exception) {
try {
val openIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(openIntent)
} catch (ignored: Exception) {
val clipboard: ClipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(getString(R.string.app_name), url)
clipboard.setPrimaryClip(clip)
Toast.makeText(this, R.string.error_opening_uri, Toast.LENGTH_LONG).show()
}
}
}
fun Context.isTablet(): Boolean {
return (resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
}
fun String.md5(): String {
val MD5 = "MD5"
try {
// Create MD5 Hash
val digest = java.security.MessageDigest
.getInstance(MD5)
digest.update(toByteArray())
val messageDigest = digest.digest()
// Create Hex String
val hexString = StringBuilder()
for (aMessageDigest in messageDigest) {
var h = Integer.toHexString(0xFF and aMessageDigest.toInt())
while (h.length < 2)
h = "0$h"
hexString.append(h)
}
return hexString.toString()
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
}
return ""
}
fun String.isValidEmail(): Boolean
= this.isNotEmpty() &&
Patterns.EMAIL_ADDRESS.matcher(this).matches()
fun Activity.isDarkTheme(): Boolean {
return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
}
fun Activity.isNotificationAccessGranted(): Boolean = Settings.Secure.getString(this.contentResolver,"enabled_notification_listeners").contains(this.packageName)
fun Float.convertDpToPixel(context: Context): Float {
val resources: Resources = context.resources
val metrics: DisplayMetrics = resources.displayMetrics
val px: Float = this * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
return px
}
fun Float.convertSpToPixels(context: Context): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, this, context.resources.displayMetrics)
}
fun Context.checkGrantedPermission(permission: String): Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}
fun Context.getCurrentWallpaper(): Drawable? = try {
WallpaperManager.getInstance(this).drawable
} catch (e: Exception) {
null
}
fun String.getCapWordString(): String {
return try {
val ar = this.split(" ")
var newText = ""
for (t: String in ar) {
newText += " "
newText += t.substring(0, 1).toUpperCase(Locale.getDefault())
newText += t.substring(1)
}
newText.substring(1)
} catch (e: Exception) {
this
}
}
fun Context.checkIfFitInstalled(): Boolean {
return try {
packageManager.getPackageInfo("com.google.android.apps.fitness", PackageManager.GET_ACTIVITIES)
true
} catch (e: Exception) {
false
}
}