Dark theme

This commit is contained in:
2021-02-20 23:21:25 +03:00
parent 88dddcb133
commit 06aa41cab1
179 changed files with 1011 additions and 1133 deletions
@@ -0,0 +1,120 @@
package com.meloda.fast.util
import android.content.ClipData
import android.content.Context
import android.content.Intent
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.DisplayMetrics
import android.util.TypedValue
import androidx.annotation.AttrRes
import com.meloda.fast.BuildConfig
import com.meloda.fast.common.AppGlobal
object AndroidUtils {
fun px(dp: Float): Float {
return dp * (AppGlobal.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
fun px(dp: Int) = px(dp.toFloat())
fun dp(px: Float): Float {
return px / (AppGlobal.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
fun dp(px: Int) = dp(px.toFloat())
fun hasConnection(): Boolean {
val network = AppGlobal.connectivityManager.activeNetwork ?: return false
val activeNetwork =
AppGlobal.connectivityManager.getNetworkCapabilities(network) ?: return false
return when {
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
else -> false
}
}
fun getDisplayWidth(): Int {
return AppGlobal.resources.displayMetrics.widthPixels
}
fun getDisplayHeight(): Int {
return AppGlobal.resources.displayMetrics.heightPixels
}
fun isDeveloperSettingsEnabled(context: Context) = Settings.Secure.getInt(
context.contentResolver,
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
0
) == 1
@Suppress("DEPRECATION")
fun isCanInstallUnknownApps(context: Context) =
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
Settings.Secure.getInt(
context.contentResolver,
Settings.Secure.INSTALL_NON_MARKET_APPS
) == 1
} else {
AppGlobal.packageManager.canRequestPackageInstalls()
}
fun openInstallUnknownAppsScreen(context: Context) {
context.startActivity(Intent().apply {
action = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
Settings.ACTION_SECURITY_SETTINGS
} else {
data = Uri.parse("package:${BuildConfig.APPLICATION_ID}")
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES
}
})
}
fun copyText(label: String? = "", text: String) {
AppGlobal.clipboardManager.setPrimaryClip(ClipData.newPlainText(label, text))
}
fun getThemeAttrColor(context: Context, @AttrRes resId: Int): Int {
// val typedValue = TypedValue()
//
// context.theme.resolveAttribute(resId, typedValue, true)
//
// return typedValue.data
val typedValue = TypedValue()
context.theme.resolveAttribute(resId, typedValue, true)
val colorRes = typedValue.resourceId
var color = -1
try {
color = context.resources.getColor(colorRes, context.theme)
} catch (e: Exception) {
}
return color
}
/*
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attributeId, typedValue, true);
int colorRes = typedValue.resourceId;
int color = -1;
try {
color = context.getResources().getColor(colorRes);
} catch (Resources.NotFoundException e) {
Log.w(TAG, "Not found color resource by id: " + colorRes);
}
return color;
*/
}
@@ -0,0 +1,64 @@
package com.meloda.fast.util
import com.meloda.fast.extensions.ArrayExtensions.asArrayList
import java.util.stream.Collectors
object ArrayUtils {
@SafeVarargs
fun <T> asString(vararg array: T): String {
if (array.isEmpty()) {
return ""
}
val builder = StringBuilder(array.size * 12)
builder.append(array[0])
for (i in 1 until array.size) {
builder.append(',')
builder.append(array[i])
}
return builder.toString()
}
fun asString(array: IntArray): String {
if (array.isEmpty()) {
return ""
}
val builder = StringBuilder(array.size * 12)
builder.append(array[0])
for (i in 1 until array.size) {
builder.append(',')
builder.append(array[i])
}
return builder.toString()
}
fun <T> asString(arrayList: ArrayList<T>): String {
// if (arrayList.isEmpty()) return ""
//
// val builder = StringBuilder(arrayList.size * 12)
// builder.append(arrayList[0])
// for (i in 1 until arrayList.size) {
// builder.append(',')
// builder.append(arrayList[i])
// }
// return builder.toString()
return ArrayList<String>().apply {
arrayList.forEach { add(it.toString()) }
}.stream().collect(Collectors.joining(","))
}
fun <T> asString(list: List<T>): String = asString(list.asArrayList())
fun <T> cut(arrayList: ArrayList<T>, offset: Int, count: Int): ArrayList<T> {
if (arrayList.isEmpty()) return arrayListOf()
var lastPosition = offset + count
if (lastPosition > arrayList.size) lastPosition = arrayList.size
return ArrayList(arrayList.subList(offset, lastPosition))
}
}
@@ -0,0 +1,14 @@
package com.meloda.fast.util
import android.content.Context
import androidx.annotation.ColorInt
import com.meloda.fast.R
object ColorUtils {
@ColorInt
fun getColorAccent(context: Context): Int {
return AndroidUtils.getThemeAttrColor(context, R.attr.colorAccent)
}
}
@@ -0,0 +1,61 @@
package com.meloda.fast.util
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.widget.ImageView
import com.facebook.drawee.view.SimpleDraweeView
import com.squareup.picasso.Picasso
import com.squareup.picasso.Target
object ImageUtils {
fun loadImage(image: String, imageView: ImageView, placeholder: Drawable?) {
if (image.isEmpty()) return
if (imageView is SimpleDraweeView) {
imageView.setImageURI(image)
return
}
val picasso = Picasso.get()
.load(image)
.priority(Picasso.Priority.LOW)
if (placeholder != null) picasso.placeholder(placeholder)
picasso.into(imageView)
}
fun loadImage(image: String?, listener: OnLoadListener?) {
if (image.isNullOrEmpty()) return
val picasso = Picasso.get()
.load(image)
.priority(Picasso.Priority.LOW)
// if (placeholder != null) picasso.placeholder(placeholder)
val target = object : Target {
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
}
override fun onBitmapFailed(e: Exception, errorDrawable: Drawable?) {
listener?.onError(e)
}
override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) {
listener?.onLoad(bitmap)
}
}
picasso.into(target)
}
interface OnLoadListener {
fun onLoad(bitmap: Bitmap)
fun onError(e: Exception)
}
}
@@ -0,0 +1,16 @@
package com.meloda.fast.util
import android.view.View
import com.meloda.fast.common.AppGlobal
object KeyboardUtils {
fun hideKeyboardFrom(view: View) {
AppGlobal.inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
fun showKeyboard(focusedView: View) {
AppGlobal.inputMethodManager.showSoftInput(focusedView, 0)
}
}
@@ -0,0 +1,15 @@
package com.meloda.fast.util
object TextUtils {
fun getFirstLetterFromString(string: String): String {
for (i in string.indices) {
val char = string[i]
if (char.isLetter()) return char.toString()
}
return ""
}
}
@@ -0,0 +1,17 @@
package com.meloda.fast.util
import java.util.*
object TimeUtils {
fun removeTime(date: Date): Long {
return Calendar.getInstance().apply {
time = date
this[Calendar.HOUR_OF_DAY] = 0
this[Calendar.MINUTE] = 0
this[Calendar.SECOND] = 0
this[Calendar.MILLISECOND] = 0
}.timeInMillis
}
}
@@ -0,0 +1,60 @@
package com.meloda.fast.util
import android.content.Context
import android.content.res.Configuration
import com.meloda.fast.R
import com.meloda.fast.common.AppGlobal
import com.meloda.fast.extensions.ArrayExtensions.isNullOrEmpty
import com.meloda.fast.io.BytesOutputStream
import java.io.ByteArrayInputStream
import java.io.IOException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
object Utils {
fun getLocalizedThrowable(context: Context, t: Throwable): String {
return context.getString(R.string.error, t.message.toString())
}
fun isDarkTheme(): Boolean {
val currentNightMode =
AppGlobal.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
return when (currentNightMode) {
Configuration.UI_MODE_NIGHT_YES -> true
else -> false
}
}
fun serialize(source: Any?): ByteArray? {
try {
val bos = BytesOutputStream()
val out = ObjectOutputStream(bos)
out.writeObject(source)
out.close()
return bos.byteArray
} catch (e: IOException) {
e.printStackTrace()
}
return null
}
fun deserialize(source: ByteArray?): Any? {
if (source.isNullOrEmpty()) {
return null
}
try {
val bis = ByteArrayInputStream(source)
val `in` = ObjectInputStream(bis)
val o = `in`.readObject()
`in`.close()
return o
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
}
@@ -0,0 +1,56 @@
package com.meloda.fast.util
import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.text.TextUtils
import android.view.View
import android.widget.TextView
import android.widget.Toast
import com.google.android.material.snackbar.Snackbar
import com.meloda.fast.R
import com.meloda.fast.api.model.VKUser
import com.meloda.fast.api.util.VKUtil
import com.meloda.fast.extensions.ContextExtensions.color
import com.meloda.fast.widget.CircleImageView
import com.squareup.picasso.Picasso
object ViewUtils {
fun showErrorSnackbar(view: View, t: Throwable) {
Snackbar.make(
view,
Utils.getLocalizedThrowable(view.context, t),
Snackbar.LENGTH_LONG
).show()
}
fun showErrorToast(context: Context, t: Throwable) {
Toast.makeText(
context,
Utils.getLocalizedThrowable(context, t),
Toast.LENGTH_LONG
).show()
}
fun prepareNavigationHeader(view: View, user: VKUser) {
val profileName = view.findViewById<TextView>(R.id.headerName)
profileName.text = user.toString()
val profileStatus = view.findViewById<TextView>(R.id.headerStatus)
val statusText = if (TextUtils.isEmpty(user.status)) "@id${user.userId}" else user.status
profileStatus.text = statusText
val profileAvatar: CircleImageView = view.findViewById(R.id.headerAvatar)
if (AndroidUtils.hasConnection()) {
Picasso.get().load(VKUtil.getUserPhoto(user)).into(profileAvatar)
} else {
profileAvatar.setImageDrawable(ColorDrawable(view.context.color(R.color.accent)))
}
}
}