diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 779462dd..c23b09d1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -78,9 +78,9 @@ android { signingConfig = signingConfigs.getByName("lastquakechilesign") resValue("string", "app_name", "LastQuakeChile") - resValue("string", "ADMOB_ID_BANNER", "ca-app-pub-6355378855577476/5493893896") - resValue("string", "ADMOB_ID_NATIVE_FRAGMENT", "ca-app-pub-6355378855577476/2611250693") - resValue("string", "ADMOB_ID_NATIVE_DETAILS", "ca-app-pub-6355378855577476/2723765487") + resValue("string", "ADMOB_ID_BANNER", "ca-app-pub-3940256099942544/6300978111") + resValue("string", "ADMOB_ID_NATIVE_FRAGMENT", "ca-app-pub-3940256099942544/2247696110") + resValue("string", "ADMOB_ID_NATIVE_DETAILS", "ca-app-pub-3940256099942544/2247696110") } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 36f38390..55112a17 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -94,10 +94,10 @@ + android:value="false" /> + android:value="false" /> \ No newline at end of file diff --git a/app/src/main/java/cl/figonzal/lastquakechile/core/utils/GoogleMapsExt.kt b/app/src/main/java/cl/figonzal/lastquakechile/core/utils/GoogleMapsExt.kt index e8a36a35..9907d441 100644 --- a/app/src/main/java/cl/figonzal/lastquakechile/core/utils/GoogleMapsExt.kt +++ b/app/src/main/java/cl/figonzal/lastquakechile/core/utils/GoogleMapsExt.kt @@ -7,9 +7,14 @@ import android.content.pm.PackageManager.ResolveInfoFlags import android.content.res.Configuration import android.net.Uri import android.os.Build -import android.view.View import cl.figonzal.lastquakechile.R -import cl.figonzal.lastquakechile.core.utils.views.* +import cl.figonzal.lastquakechile.core.utils.views.configSensitive +import cl.figonzal.lastquakechile.core.utils.views.formatFilterColor +import cl.figonzal.lastquakechile.core.utils.views.formatMagnitude +import cl.figonzal.lastquakechile.core.utils.views.formatQuakeTime +import cl.figonzal.lastquakechile.core.utils.views.getLocalBitmapUri +import cl.figonzal.lastquakechile.core.utils.views.getMagnitudeColor +import cl.figonzal.lastquakechile.core.utils.views.toast import cl.figonzal.lastquakechile.databinding.QuakeBottomSheetBinding import cl.figonzal.lastquakechile.quake_feature.domain.model.Quake import com.google.android.gms.maps.GoogleMap @@ -92,14 +97,16 @@ fun Circle.animate(body: Circle.() -> Unit): Circle { /** * Google maps take snapshot */ -fun Context.makeSnapshot(googleMap: GoogleMap, quake: Quake) { +fun Context.makeSnapshot(googleMap: GoogleMap, quake: Quake, callback: (Uri?) -> Unit) { googleMap.snapshot { try { Timber.d("Snapshot google map") val bitMapUri = it?.let { it1 -> this.getLocalBitmapUri(it1) } - shareQuake(quake, bitMapUri) + callback(bitMapUri) + + //shareQuake(quake, bitMapUri) } catch (e: IOException) { Timber.e(e, "Error screenshot map: %s", e.message) } @@ -146,6 +153,7 @@ private fun Context.shareQuake(quake: Quake, bitMapUri: Uri?) { chooser, ResolveInfoFlags.of(MATCH_DEFAULT_ONLY.toLong()) ) + else -> packageManager.queryIntentActivities(chooser, MATCH_DEFAULT_ONLY) } @@ -176,26 +184,17 @@ fun Context.setBottomSheetQuakeData( tvCity.text = quake.city tvReference.text = quake.reference - tvMagnitude.text = String.format( - QUAKE_DETAILS_MAGNITUDE_FORMAT, - quake.magnitude - ) - ivMagColor.setColorFilter( - resources.getColor( - getMagnitudeColor(quake.magnitude, false), theme - ) - ) + tvMagnitude.formatMagnitude(quake) - tvDate.timeToText(quake, true) + ivMagColor.formatFilterColor(applicationContext, quake) - //Verified status - ivVerified.visibility = when { - quake.isVerified -> View.VISIBLE - else -> View.GONE - } + tvDate.formatQuakeTime(quake, true) - ivVerified.setOnClickListener { - toast(R.string.quake_verified_toast) + with(ivVerified) { + configSensitive(quake) + setOnClickListener { + toast(R.string.quake_verified_toast) + } } root.setOnClickListener { diff --git a/app/src/main/java/cl/figonzal/lastquakechile/core/utils/views/FormatExt.kt b/app/src/main/java/cl/figonzal/lastquakechile/core/utils/views/FormatExt.kt new file mode 100644 index 00000000..35915994 --- /dev/null +++ b/app/src/main/java/cl/figonzal/lastquakechile/core/utils/views/FormatExt.kt @@ -0,0 +1,224 @@ +package cl.figonzal.lastquakechile.core.utils.views + +import android.content.Context +import android.widget.ImageView +import android.widget.TextView +import cl.figonzal.lastquakechile.R +import cl.figonzal.lastquakechile.core.utils.latLongToDMS +import cl.figonzal.lastquakechile.core.utils.localDateToDHMS +import cl.figonzal.lastquakechile.core.utils.stringToLocalDateTime +import cl.figonzal.lastquakechile.quake_feature.domain.model.Quake +import java.time.format.DateTimeFormatter +import java.util.Locale + +/** + * Setting scale textview depending on the value of string + * + * @param quake Quake information + */ +fun TextView.formatScale(quake: Quake) { + + text = when (quake.scale.lowercase()) { + "mw" -> String.format( + QUAKE_DETAILS_SCALE_FORMAT, + context.getString(R.string.moment_magnitude) + ) + + "mww" -> String.format( + QUAKE_DETAILS_SCALE_FORMAT, + context.getString(R.string.moment_magnitude_w) + ) + + else -> String.format( + QUAKE_DETAILS_SCALE_FORMAT, + context.getString(R.string.local_magnitude) + ) + } +} + +fun TextView.formatDepth(quake: Quake) { + text = String.format(QUAKE_DETAILS_DEPTH_FORMAT, quake.depth) +} + +/** + * Format text for quake magnitude + * + * @param quake Quake information + */ +fun TextView.formatMagnitude(quake: Quake) { + text = String.format( + QUAKE_DETAILS_MAGNITUDE_FORMAT, + quake.magnitude + ) +} + +fun ImageView.formatFilterColor(context: Context, quake: Quake) = + this.setColorFilter(context.getColor(getMagnitudeColor(quake.magnitude, false))) + + +fun TextView.formatDateTime(quake: Quake) { + text = quake.localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +} + +/** + * Transform localDateTime to a string text in (days or hours or minutes) + */ +fun TextView.formatQuakeTime(quake: Quake, isShortVersion: Boolean = false) { + + val timeMap = quake.localDate.stringToLocalDateTime().localDateToDHMS() + val days = timeMap[DAYS] + + text = when { + days != null && days == 0L -> { + calculateTextViewBelowDay(this.context, timeMap, isShortVersion) + } + + days != null && days > 0 -> { + calculateTextViewAboveDay(this.context, timeMap, isShortVersion) + } + + else -> "" + } +} + +/** + * Coordinates to DMS + */ +fun TextView.formatDMS(quake: Quake) { + + val latDMS = quake.coordinate.latitude.latLongToDMS() + val degreeLat = latDMS["grados"] + val minLat = latDMS["minutos"] + val segLat = latDMS["segundos"] + + val dmsLat = String.format( + Locale.US, + "%.1f° %.1f' %.1f'' %s", + degreeLat, + minLat, + segLat, + when { + quake.coordinate.latitude < 0 -> this.context.getString(R.string.south_cords) + else -> this.context.getString(R.string.north_cords) + } + ) + + val longDMS = quake.coordinate.longitude.latLongToDMS() + val degreeLong = longDMS["grados"] + val minLong = longDMS["minutos"] + val segLong = longDMS["segundos"] + + val dmsLong = String.format( + Locale.US, + "%.1f° %.1f' %.1f'' %s", + degreeLong, + minLong, + segLong, + when { + quake.coordinate.longitude < 0 -> this.context.getString(R.string.west_cords) + else -> this.context.getString(R.string.east_cords) + } + ) + + text = String.format(QUAKE_CORDS_FORMAT, dmsLat, dmsLong) +} + +fun Context.getMonth(month: Int) = arrayOf( + getString(R.string.JAN), + getString(R.string.FEB), + getString(R.string.MAR), + getString(R.string.APR), + getString(R.string.MAY), + getString(R.string.JUN), + getString(R.string.JUL), + getString(R.string.AUG), + getString(R.string.SEP), + getString(R.string.OCT), + getString(R.string.NOV), + getString(R.string.DEC) +)[month - 1] + +private fun calculateTextViewBelowDay( + context: Context, + timeMap: Map, + isShortVersion: Boolean +): String { + + val hour = timeMap[HOURS] + val min = timeMap[MINUTES] + val seg = timeMap[SECONDS] + + return when { + hour != null && hour >= 1 -> when { + isShortVersion -> String.format(QUAKETIME_H_FORMAT, hour) + else -> String.format(context.getString(R.string.quake_time_hour_info_windows), hour) + } + + else -> when { + min != null && min < 1 -> when { + isShortVersion -> String.format( + QUAKETIME_S_FORMAT, seg + ) + + else -> String.format( + context.getString(R.string.quake_time_second_info_windows), seg + ) + } + + else -> when { + isShortVersion -> String.format( + QUAKETIME_M_FORMAT, + min + ) + + else -> String.format( + context.getString(R.string.quake_time_minute_info_windows), + min + ) + } + } + } +} + + +private fun calculateTextViewAboveDay( + context: Context, + timeMap: Map, + isShortVersion: Boolean +): String { + + val days = timeMap[DAYS] + val hour = timeMap[HOURS] + + return when { + hour != null && hour == 0L -> when { + isShortVersion -> String.format( + QUAKETIME_D_FORMAT, + days + ) + + else -> String.format( + context.getString(R.string.quake_time_day_info_windows), + days + ) + } + + hour != null && hour >= 1 -> when { + isShortVersion -> String.format( + QUAKETIME_DH_FORMAT, + days, + hour / 24 + ) + + else -> String.format( + context.getString(R.string.quake_time_day_hour_info_windows), + days, + hour / 24 + ) + } + + else -> "" + } +} + + diff --git a/app/src/main/java/cl/figonzal/lastquakechile/core/utils/views/ViewsExt.kt b/app/src/main/java/cl/figonzal/lastquakechile/core/utils/views/ViewsExt.kt index af8927d6..aecd00a2 100644 --- a/app/src/main/java/cl/figonzal/lastquakechile/core/utils/views/ViewsExt.kt +++ b/app/src/main/java/cl/figonzal/lastquakechile/core/utils/views/ViewsExt.kt @@ -9,7 +9,6 @@ import android.net.Uri import android.util.TypedValue import android.view.* import android.widget.ImageView -import android.widget.TextView import android.widget.Toast import androidx.annotation.MenuRes import androidx.core.content.FileProvider.getUriForFile @@ -22,12 +21,8 @@ import cl.figonzal.lastquakechile.R import cl.figonzal.lastquakechile.core.data.remote.ApiError import cl.figonzal.lastquakechile.core.data.remote.ApiError.* import cl.figonzal.lastquakechile.core.ui.SettingsActivity -import cl.figonzal.lastquakechile.core.utils.latLongToDMS -import cl.figonzal.lastquakechile.core.utils.localDateToDHMS -import cl.figonzal.lastquakechile.core.utils.stringToLocalDateTime import cl.figonzal.lastquakechile.core.utils.views.* import cl.figonzal.lastquakechile.databinding.FragmentMapsBinding -import cl.figonzal.lastquakechile.quake_feature.domain.model.Coordinate import cl.figonzal.lastquakechile.quake_feature.domain.model.Quake import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy @@ -117,52 +112,23 @@ fun getMagnitudeColor(magnitude: Double, forMapa: Boolean) = when { else -> getColorResource(floor(magnitude).toInt()) } -private fun getColorResource(mMagFloor: Int) = when { - mMagFloor == 1 -> R.color.magnitude1 - mMagFloor == 2 -> R.color.magnitude2 - mMagFloor == 3 -> R.color.magnitude3 - mMagFloor == 4 -> R.color.magnitude4 - mMagFloor == 5 -> R.color.magnitude5 - mMagFloor == 6 -> R.color.magnitude6 - mMagFloor == 7 -> R.color.magnitude7 - mMagFloor >= 8 -> R.color.magnitude8 - else -> R.color.colorPrimary -} - -private fun getColorResourceMap(mMagFloor: Int) = when { - mMagFloor == 1 -> R.color.magnitude1_alpha - mMagFloor == 2 -> R.color.magnitude2_alpha - mMagFloor == 3 -> R.color.magnitude3_alpha - mMagFloor == 4 -> R.color.magnitude4_alpha - mMagFloor == 5 -> R.color.magnitude5_alpha - mMagFloor == 6 -> R.color.magnitude6_alpha - mMagFloor == 7 -> R.color.magnitude7_alpha - mMagFloor >= 8 -> R.color.magnitude8_alpha - else -> R.color.colorPrimary -} - /** * Inflater any view */ fun ViewGroup.layoutInflater(layout: Int): View = LayoutInflater.from(context).inflate(layout, this, false) -/** - * Setting scale textview depending on the value of string - * - * @param scale Quake scale - */ -fun TextView.setScale(scale: String) { - text = when { - scale.contains("Mw") -> String.format( - QUAKE_DETAILS_SCALE_FORMAT, - context.getString(R.string.moment_magnitude) - ) +fun ImageView.configSensitive(quake: Quake) { + visibility = when { + quake.isSensitive -> View.VISIBLE + else -> View.GONE + } +} - else -> String.format( - QUAKE_DETAILS_SCALE_FORMAT, - context.getString(R.string.local_magnitude) - ) +fun ImageView.configVerified(quake: Quake) { + visibility = when { + quake.isVerified -> View.VISIBLE + else -> View.GONE } } @@ -194,151 +160,6 @@ fun Context.toast(stringId: Int) { } -/** - * Transform localDateTime to a string text in (days or hours or minutes) - */ -fun TextView.timeToText(quake: Quake, isShortVersion: Boolean = false) { - - val timeMap = quake.localDate.stringToLocalDateTime().localDateToDHMS() - val days = timeMap[DAYS] - - text = when { - days != null && days == 0L -> { - calculateTextViewBelowDay(this.context, timeMap, isShortVersion) - } - - days != null && days > 0 -> { - calculateTextViewAboveDay(this.context, timeMap, isShortVersion) - } - - else -> "" - } -} - -private fun calculateTextViewAboveDay( - context: Context, - timeMap: Map, - isShortVersion: Boolean -): String { - - val days = timeMap[DAYS] - val hour = timeMap[HOURS] - - return when { - hour != null && hour == 0L -> when { - isShortVersion -> String.format( - QUAKETIME_D_FORMAT, - days - ) - - else -> String.format( - context.getString(R.string.quake_time_day_info_windows), - days - ) - } - - hour != null && hour >= 1 -> when { - isShortVersion -> String.format( - QUAKETIME_DH_FORMAT, - days, - hour / 24 - ) - - else -> String.format( - context.getString(R.string.quake_time_day_hour_info_windows), - days, - hour / 24 - ) - } - - else -> "" - } -} - -private fun calculateTextViewBelowDay( - context: Context, - timeMap: Map, - isShortVersion: Boolean -): String { - - val hour = timeMap[HOURS] - val min = timeMap[MINUTES] - val seg = timeMap[SECONDS] - - return when { - hour != null && hour >= 1 -> when { - isShortVersion -> String.format(QUAKETIME_H_FORMAT, hour) - else -> String.format(context.getString(R.string.quake_time_hour_info_windows), hour) - } - - else -> when { - min != null && min < 1 -> when { - isShortVersion -> String.format( - QUAKETIME_S_FORMAT, seg - ) - - else -> String.format( - context.getString(R.string.quake_time_second_info_windows), seg - ) - } - - else -> when { - isShortVersion -> String.format( - QUAKETIME_M_FORMAT, - min - ) - - else -> String.format( - context.getString(R.string.quake_time_minute_info_windows), - min - ) - } - } - } -} - -/** - * Coordinates to DMS - */ -fun TextView.formatDMS(coordinates: Coordinate) { - - val latDMS = coordinates.latitude.latLongToDMS() - val degreeLat = latDMS["grados"] - val minLat = latDMS["minutos"] - val segLat = latDMS["segundos"] - - val dmsLat = String.format( - Locale.US, - "%.1f° %.1f' %.1f'' %s", - degreeLat, - minLat, - segLat, - when { - coordinates.latitude < 0 -> this.context.getString(R.string.south_cords) - else -> this.context.getString(R.string.north_cords) - } - ) - - val longDMS = coordinates.longitude.latLongToDMS() - val degreeLong = longDMS["grados"] - val minLong = longDMS["minutos"] - val segLong = longDMS["segundos"] - - val dmsLong = String.format( - Locale.US, - "%.1f° %.1f' %.1f'' %s", - degreeLong, - minLong, - segLong, - when { - coordinates.longitude < 0 -> this.context.getString(R.string.west_cords) - else -> this.context.getString(R.string.east_cords) - } - ) - - text = String.format(QUAKE_CORDS_FORMAT, dmsLat, dmsLong) -} - /** * Save snapshot from google map in cache directory */ @@ -397,20 +218,6 @@ fun Context.loadImage(url: Int, imageView: ImageView) = Glide.with(this) .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC) .into(imageView) -fun Context.getMonth(month: Int) = arrayOf( - getString(R.string.JAN), - getString(R.string.FEB), - getString(R.string.MAR), - getString(R.string.APR), - getString(R.string.MAY), - getString(R.string.JUN), - getString(R.string.JUL), - getString(R.string.AUG), - getString(R.string.SEP), - getString(R.string.OCT), - getString(R.string.NOV), - getString(R.string.DEC) -)[month - 1] fun Fragment.showServerApiError(apiError: ApiError, callback: (Int, String) -> Unit) = when (apiError) { @@ -473,18 +280,6 @@ fun BottomSheetBehavior.configBottomSheetCallback( } } -private fun GoogleMap.adjustMapPadding(binding: FragmentMapsBinding) { - val bottomSheetContainerHeight = binding.include.root.height - val currentBottomSheetTop = binding.include.cvBottomSheet.top - - this.setPadding( - 0, // left - 0, // top - 0, // right - bottomSheetContainerHeight - currentBottomSheetTop // bottom - ) -} - fun Float.toDips(resources: Resources) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, resources.displayMetrics) @@ -504,3 +299,45 @@ fun ViewGroup.getViewBottomHeight( viewTreeObserver.addOnGlobalLayoutListener(callback) } +/** + * Get color resources depending on magnitude value + */ +private fun getColorResource(mMagFloor: Int) = when { + mMagFloor == 1 -> R.color.magnitude1 + mMagFloor == 2 -> R.color.magnitude2 + mMagFloor == 3 -> R.color.magnitude3 + mMagFloor == 4 -> R.color.magnitude4 + mMagFloor == 5 -> R.color.magnitude5 + mMagFloor == 6 -> R.color.magnitude6 + mMagFloor == 7 -> R.color.magnitude7 + mMagFloor >= 8 -> R.color.magnitude8 + else -> R.color.colorPrimary +} + +/** + * Get color resources depending on magnitude value + */ +private fun getColorResourceMap(mMagFloor: Int) = when { + mMagFloor == 1 -> R.color.magnitude1_alpha + mMagFloor == 2 -> R.color.magnitude2_alpha + mMagFloor == 3 -> R.color.magnitude3_alpha + mMagFloor == 4 -> R.color.magnitude4_alpha + mMagFloor == 5 -> R.color.magnitude5_alpha + mMagFloor == 6 -> R.color.magnitude6_alpha + mMagFloor == 7 -> R.color.magnitude7_alpha + mMagFloor >= 8 -> R.color.magnitude8_alpha + else -> R.color.colorPrimary +} + +private fun GoogleMap.adjustMapPadding(binding: FragmentMapsBinding) { + val bottomSheetContainerHeight = binding.include.root.height + val currentBottomSheetTop = binding.include.cvBottomSheet.top + + this.setPadding( + 0, // left + 0, // top + 0, // right + bottomSheetContainerHeight - currentBottomSheetTop // bottom + ) +} + diff --git a/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeAdapter.kt b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeAdapter.kt index 97a8c575..5b5739df 100644 --- a/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeAdapter.kt +++ b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeAdapter.kt @@ -7,10 +7,12 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import cl.figonzal.lastquakechile.R import cl.figonzal.lastquakechile.core.utils.openQuakeDetails -import cl.figonzal.lastquakechile.core.utils.views.QUAKE_DETAILS_MAGNITUDE_FORMAT -import cl.figonzal.lastquakechile.core.utils.views.getMagnitudeColor +import cl.figonzal.lastquakechile.core.utils.views.configSensitive +import cl.figonzal.lastquakechile.core.utils.views.configVerified +import cl.figonzal.lastquakechile.core.utils.views.formatFilterColor +import cl.figonzal.lastquakechile.core.utils.views.formatMagnitude +import cl.figonzal.lastquakechile.core.utils.views.formatQuakeTime import cl.figonzal.lastquakechile.core.utils.views.layoutInflater -import cl.figonzal.lastquakechile.core.utils.views.timeToText import cl.figonzal.lastquakechile.core.utils.views.toast import cl.figonzal.lastquakechile.databinding.CardViewQuakeBinding import cl.figonzal.lastquakechile.quake_feature.domain.model.Quake @@ -63,30 +65,19 @@ class QuakeAdapter : RecyclerView.Adapter() { tvCity.text = quake.city tvReference.text = quake.reference - tvMagnitude.text = String.format( - QUAKE_DETAILS_MAGNITUDE_FORMAT, quake.magnitude - ) + tvMagnitude.formatMagnitude(quake) - val idColor = getMagnitudeColor(quake.magnitude, false) - ivMagColor.setColorFilter( - itemView.resources.getColor(idColor, itemView.context.theme) - ) + ivMagColor.formatFilterColor(itemView.context, quake) - tvHour.timeToText(quake, true) + tvHour.formatQuakeTime(quake, true) - ivSensitive.visibility = when { - quake.isSensitive -> View.VISIBLE - else -> View.GONE - } - - //Verified status - ivVerified.visibility = when { - quake.isVerified -> View.VISIBLE - else -> View.GONE - } + ivSensitive.configSensitive(quake) - ivVerified.setOnClickListener { - itemView.context.toast(R.string.quake_verified_toast) + with(ivVerified) { + configVerified(quake) + setOnClickListener { + itemView.context.toast(R.string.quake_verified_toast) + } } root.setOnClickListener { itemView.context.openQuakeDetails(quake) } @@ -97,10 +88,10 @@ class QuakeAdapter : RecyclerView.Adapter() { /*** * Function that recalculate the time difference between quake time and device time */ - fun recalculateTimeShowed() { + private fun recalculateTimeShowed() { quakes.forEachIndexed { index, quake -> - binding?.tvHour?.timeToText(quake, true) + binding?.tvHour?.formatQuakeTime(quake, true) notifyItemChanged(index) } Timber.d("Recalculating time shown in quakeList") diff --git a/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeDetailsActivity.kt b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeDetailsActivity.kt index 9c36e7fa..be70ec84 100644 --- a/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeDetailsActivity.kt +++ b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/QuakeDetailsActivity.kt @@ -3,6 +3,9 @@ package cl.figonzal.lastquakechile.quake_feature.ui import android.animation.IntEvaluator import android.animation.ValueAnimator import android.annotation.SuppressLint +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.Canvas import android.graphics.Color import android.os.Build import android.os.Bundle @@ -14,6 +17,7 @@ import android.view.animation.AccelerateDecelerateInterpolator import android.widget.ImageView import android.widget.RatingBar import android.widget.TextView +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.os.BundleCompat import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen @@ -23,11 +27,12 @@ import androidx.lifecycle.lifecycleScope import cl.figonzal.lastquakechile.R import cl.figonzal.lastquakechile.core.services.notifications.utils.IS_SNAPSHOT_REQUEST_FROM_BOTTOM_SHEET import cl.figonzal.lastquakechile.core.services.notifications.utils.QUAKE -import cl.figonzal.lastquakechile.core.ui.dialog.MapTerrainDialogFragment import cl.figonzal.lastquakechile.core.utils.* import cl.figonzal.lastquakechile.core.utils.views.* import cl.figonzal.lastquakechile.databinding.ActivityQuakeDetailsBinding import cl.figonzal.lastquakechile.quake_feature.domain.model.Quake +import cl.figonzal.lastquakechile.quake_feature.ui.dialog.MapTerrainDialogFragment +import cl.figonzal.lastquakechile.quake_feature.ui.dialog.ShareQuakeBottomSheetDialog import com.google.android.gms.ads.* import com.google.android.gms.ads.nativead.NativeAd import com.google.android.gms.ads.nativead.NativeAdView @@ -38,7 +43,7 @@ import com.google.android.gms.maps.model.LatLng import com.google.maps.android.ktx.addCircle import kotlinx.coroutines.* import timber.log.Timber -import java.time.format.DateTimeFormatter + private const val mapViewKey = "MapViewBundleKey" @@ -87,6 +92,7 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { this?.let { BundleCompat.getParcelable(it, QUAKE, Quake::class.java) } } + else -> this?.get(QUAKE) as Quake } isSnapshotRequest = this?.getBoolean(IS_SNAPSHOT_REQUEST_FROM_BOTTOM_SHEET) as Boolean @@ -173,6 +179,7 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { null -> { View.INVISIBLE } + else -> { nativeAd.starRating?.let { (starRatingView as RatingBar).rating = it.toFloat() @@ -192,6 +199,7 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { vc?.hasVideoContent() == true -> vc.videoLifecycleCallbacks = object : VideoController.VideoLifecycleCallbacks() { } + else -> { //refreshAd() } @@ -210,36 +218,27 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { tvReference.text = it.reference - tvMagnitude.text = - String.format(QUAKE_DETAILS_MAGNITUDE_FORMAT, it.magnitude) + tvMagnitude.formatMagnitude(it) - ivMagColor.setColorFilter(getColor(getMagnitudeColor(it.magnitude, false))) + ivMagColor.formatFilterColor(this@QuakeDetailsActivity, it) - tvDepthValue.text = - String.format(QUAKE_DETAILS_DEPTH_FORMAT, it.depth) + tvDepthValue.formatDepth(it) - tvDatetimeValue.text = - it.localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + tvDatetimeValue.formatDateTime(it) - tvGmsValue.formatDMS(it.coordinate) + tvGmsValue.formatDMS(it) - tvHour.timeToText(it, true) + tvHour.formatQuakeTime(it, true) - tvScaleValue.setScale(it.scale) + tvScaleValue.formatScale(it) - ivSensitive.visibility = when { - it.isSensitive -> View.VISIBLE - else -> View.GONE - } - - //Verified status - ivVerified.visibility = when { - it.isVerified -> View.VISIBLE - else -> View.GONE - } + ivSensitive.configSensitive(it) - ivVerified.setOnClickListener { - toast(R.string.quake_verified_toast) + with(ivVerified) { + configVerified(it) + setOnClickListener { + toast(R.string.quake_verified_toast) + } } } } @@ -249,12 +248,12 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { googleMap = p0 - quake?.let { + quake?.let { quake -> - val quakeMagColor = getColor(getMagnitudeColor(it.magnitude, true)) + val quakeMagColor = getColor(getMagnitudeColor(quake.magnitude, true)) val greyAlpha = getColor(R.color.grey_dark_alpha) - val latLong = LatLng(it.coordinate.latitude, it.coordinate.longitude) + val latLong = LatLng(quake.coordinate.latitude, quake.coordinate.longitude) p0.apply { @@ -336,15 +335,33 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { //Seteo de floating buttons binding.fabShare.setOnClickListener { _ -> Timber.d("Share button clicked") - this@QuakeDetailsActivity.makeSnapshot(p0, it) + this@QuakeDetailsActivity.makeSnapshot(p0, quake) { uri -> + uri?.let { + Toast.makeText( + this@QuakeDetailsActivity, + "Snapshot correct", + Toast.LENGTH_LONG + ).show() + + val shareQuakeBottomSheetDialog = ShareQuakeBottomSheetDialog(it, quake) + shareQuakeBottomSheetDialog.show( + supportFragmentManager, + "ShareQuakeBottomSheetDialog" + ) + + } + } + + + //instagramShareIntent() } if (isSnapshotRequest == true) { Timber.d("Snapshot request from bottomSheetDialog") lifecycleScope.launch { - delay(1000) - this@QuakeDetailsActivity.makeSnapshot(p0, it) + //delay(1000) + //this@QuakeDetailsActivity.makeSnapshot(p0, it) } } } @@ -364,6 +381,49 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { } } + private fun instagramShareIntent() { + + // Crear la vista fuera de la pantalla + // Crear la vista fuera de la pantalla + val view = View(this) + view.layout(0, 0, 40, 50) + view.draw(Canvas()) + +// Convertir la vista en un Bitmap + +// Convertir la vista en un Bitmap + val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + view.draw(canvas) + + val bitMapUriView = getLocalBitmapUri(bitmap) + + grantUriPermission( + "com.instagram.android", + bitMapUriView, + Intent.FLAG_GRANT_READ_URI_PERMISSION + ) + + val intent = Intent("com.instagram.share.ADD_TO_STORY").apply { + + type = "image/*" + putExtra("source_application", "740961793640508") + putExtra("interactive_asset_uri", bitMapUriView) + putExtra("top_background_color", "#006994"); + putExtra("bottom_background_color", "#006994"); + } + startActivity(intent) + } + + fun viewToBitmap(view: View): Bitmap { + val bitmap = Bitmap.createBitmap( + view.width, view.height, Bitmap.Config.ARGB_8888 + ) + val canvas = Canvas(bitmap) + view.draw(canvas) + return bitmap + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) @@ -423,6 +483,7 @@ class QuakeDetailsActivity : AppCompatActivity(), OnMapReadyCallback { Timber.d("Home up clicked") finish() } + R.id.layers_menu -> { googleMap?.let { diff --git a/app/src/main/java/cl/figonzal/lastquakechile/core/ui/dialog/MapTerrainDialogFragment.kt b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/dialog/MapTerrainDialogFragment.kt similarity index 82% rename from app/src/main/java/cl/figonzal/lastquakechile/core/ui/dialog/MapTerrainDialogFragment.kt rename to app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/dialog/MapTerrainDialogFragment.kt index b3df73b1..f0f88d02 100644 --- a/app/src/main/java/cl/figonzal/lastquakechile/core/ui/dialog/MapTerrainDialogFragment.kt +++ b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/dialog/MapTerrainDialogFragment.kt @@ -1,4 +1,4 @@ -package cl.figonzal.lastquakechile.core.ui.dialog +package cl.figonzal.lastquakechile.quake_feature.ui.dialog import android.app.Dialog import android.os.Bundle @@ -8,7 +8,10 @@ import cl.figonzal.lastquakechile.R import cl.figonzal.lastquakechile.core.utils.SHARED_PREF_MAP_TYPE import cl.figonzal.lastquakechile.core.utils.SharedPrefUtil import com.google.android.gms.maps.GoogleMap -import com.google.android.gms.maps.GoogleMap.* +import com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID +import com.google.android.gms.maps.GoogleMap.MAP_TYPE_NONE +import com.google.android.gms.maps.GoogleMap.MAP_TYPE_NORMAL +import com.google.android.gms.maps.GoogleMap.MAP_TYPE_TERRAIN class MapTerrainDialogFragment(private val googleMap: GoogleMap) : DialogFragment() { diff --git a/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/dialog/ShareQuakeBottomSheetDialog.kt b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/dialog/ShareQuakeBottomSheetDialog.kt new file mode 100644 index 00000000..3bc90594 --- /dev/null +++ b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/dialog/ShareQuakeBottomSheetDialog.kt @@ -0,0 +1,104 @@ +package cl.figonzal.lastquakechile.quake_feature.ui.dialog + +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.drawable.Drawable +import android.net.Uri +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import cl.figonzal.lastquakechile.core.utils.views.formatFilterColor +import cl.figonzal.lastquakechile.core.utils.views.formatMagnitude +import cl.figonzal.lastquakechile.core.utils.views.formatQuakeTime +import cl.figonzal.lastquakechile.core.utils.views.getLocalBitmapUri +import cl.figonzal.lastquakechile.databinding.ShareQuakeBottomSheetBinding +import cl.figonzal.lastquakechile.quake_feature.domain.model.Quake +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.google.android.material.shape.CornerFamily +import com.google.android.material.shape.ShapeAppearanceModel + + +class ShareQuakeBottomSheetDialog(private val quakeBitmapUri: Uri, private val quake: Quake) : + BottomSheetDialogFragment() { + + private var _binding: ShareQuakeBottomSheetBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + + _binding = ShareQuakeBottomSheetBinding.inflate(layoutInflater, container, false) + + val inputStream = requireContext().contentResolver.openInputStream(quakeBitmapUri) + val drawable = Drawable.createFromStream(inputStream, quakeBitmapUri.toString()) + + with(binding.includeShareQuake) { + + val shapeAppearanceModel = ShapeAppearanceModel() + .toBuilder() + .setTopLeftCorner(CornerFamily.ROUNDED, 32f) + .setTopRightCorner(CornerFamily.ROUNDED, 32f) + .build() + ivGoogleMaps.setImageDrawable(drawable) + ivGoogleMaps.shapeAppearanceModel = shapeAppearanceModel + + with(sheetContent) { + tvCity.text = quake.city + tvMagnitude.formatMagnitude(quake) + tvDate.formatQuakeTime(quake, true) + tvReference.text = quake.reference + ivMagColor.formatFilterColor(requireContext(), quake) + } + } + + binding.btnShareIgStory.setOnClickListener { + instagramShareIntent() + } + + return binding.root + } + + private fun instagramShareIntent() { + + val bitmap = viewToBitmap(binding.includeShareQuake.cvShareQuake) + val bitMapUriView = requireContext().getLocalBitmapUri(bitmap) + + requireContext().grantUriPermission( + "com.instagram.android", + bitMapUriView, + Intent.FLAG_GRANT_READ_URI_PERMISSION + ) + + val intent = Intent("com.instagram.share.ADD_TO_STORY").apply { + + type = "image/*" + putExtra("source_application", "740961793640508") + putExtra("interactive_asset_uri", bitMapUriView) + putExtra("top_background_color", "#006994"); + putExtra("bottom_background_color", "#006994"); + } + startActivity(intent) + } + + private fun viewToBitmap(view: View): Bitmap { + view.setLayerType(View.LAYER_TYPE_SOFTWARE, null) + val totalHeight = view.height + val totalWidth = view.width + val percent = 1.0f //use this value to scale bitmap to specific size + + + val canvasBitmap = Bitmap.createBitmap(totalWidth, totalHeight, Bitmap.Config.ARGB_8888) + canvasBitmap.eraseColor(Color.RED) + val canvas = Canvas(canvasBitmap) + canvas.scale(percent, percent) + view.draw(canvas) + + return canvasBitmap + } +} \ No newline at end of file diff --git a/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/map/MapsFragment.kt b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/map/MapsFragment.kt index 830c47d2..7c8c2b0e 100644 --- a/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/map/MapsFragment.kt +++ b/app/src/main/java/cl/figonzal/lastquakechile/quake_feature/ui/map/MapsFragment.kt @@ -10,7 +10,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import cl.figonzal.lastquakechile.R -import cl.figonzal.lastquakechile.core.ui.dialog.MapTerrainDialogFragment import cl.figonzal.lastquakechile.core.utils.* import cl.figonzal.lastquakechile.core.utils.views.configBottomSheetCallback import cl.figonzal.lastquakechile.core.utils.views.configOptionsMenu @@ -19,6 +18,7 @@ import cl.figonzal.lastquakechile.core.utils.views.handleBottomSheetState import cl.figonzal.lastquakechile.databinding.FragmentMapsBinding import cl.figonzal.lastquakechile.quake_feature.domain.model.Quake import cl.figonzal.lastquakechile.quake_feature.ui.QuakeViewModel +import cl.figonzal.lastquakechile.quake_feature.ui.dialog.MapTerrainDialogFragment import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.GoogleMap.* diff --git a/app/src/main/res/drawable/round_add_instagram_story.xml b/app/src/main/res/drawable/round_add_instagram_story.xml new file mode 100644 index 00000000..67869728 --- /dev/null +++ b/app/src/main/res/drawable/round_add_instagram_story.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_quake_details.xml b/app/src/main/res/layout/activity_quake_details.xml index 52aa9fed..725d9768 100644 --- a/app/src/main/res/layout/activity_quake_details.xml +++ b/app/src/main/res/layout/activity_quake_details.xml @@ -111,6 +111,7 @@ + - + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/share_quake_bottom_sheet.xml b/app/src/main/res/layout/share_quake_bottom_sheet.xml new file mode 100644 index 00000000..aece5dca --- /dev/null +++ b/app/src/main/res/layout/share_quake_bottom_sheet.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index ae841603..10ea4872 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -154,5 +154,6 @@ Permission disabled, reinstall to enabled it Consent Policy Personalized advertising + Moment magnitude w phase (Mww) \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index a25ccb61..175f03a3 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -12,6 +12,7 @@ Escala Magnitud local (Ml) Magnitud Momento (Mw) + Magnitud Momento fase w (Mww) Icono sismo sensible Alerta sismos Recibe alertas de sismos diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b0eb6fb6..ba7c0101 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -206,6 +206,7 @@ -Mejoras, novedades Consent Policy Personalized advertising + Moment magnitude w phase (Mww) \ No newline at end of file