Signal-Android/app/src/main/java/org/thoughtcrime/securesms/stories/StoryFirstTimeNavigationVie...

170 wiersze
4.8 KiB
Kotlin
Czysty Zwykły widok Historia

package org.thoughtcrime.securesms.stories
2022-10-27 16:43:52 +00:00
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.util.AttributeSet
import android.view.View
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
2022-10-27 16:43:52 +00:00
import com.airbnb.lottie.LottieAnimationView
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.blurhash.BlurHash
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.util.ContextUtil
import org.thoughtcrime.securesms.util.visible
class StoryFirstTimeNavigationView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs) {
companion object {
private const val BLUR_ALPHA = 0x3D
2022-10-27 16:43:52 +00:00
private const val NO_BLUR_ALPHA = 0xCC
}
init {
inflate(context, R.layout.story_first_time_navigation_view, this)
}
2022-10-27 16:43:52 +00:00
private val tapToAdvance: LottieAnimationView = findViewById(R.id.edu_tap_icon)
private val swipeUp: LottieAnimationView = findViewById(R.id.edu_swipe_up_icon)
private val swipeRight: LottieAnimationView = findViewById(R.id.edu_swipe_right_icon)
private val blurHashView: ImageView = findViewById(R.id.edu_blur_hash)
private val overlayView: ImageView = findViewById(R.id.edu_overlay)
private val gotIt: View = findViewById(R.id.edu_got_it)
2022-10-27 16:43:52 +00:00
private val close: View = findViewById(R.id.edu_close)
2022-10-27 16:43:52 +00:00
private var isPlayingAnimations = false
var callback: Callback? = null
init {
if (isRenderEffectSupported()) {
blurHashView.visible = false
overlayView.visible = true
overlayView.setImageDrawable(ColorDrawable(Color.argb(BLUR_ALPHA, 0, 0, 0)))
}
gotIt.setOnClickListener {
callback?.onGotItClicked()
GlideApp.with(this).clear(blurHashView)
blurHashView.setImageDrawable(null)
hide()
}
2022-10-27 16:43:52 +00:00
close.setOnClickListener {
callback?.onCloseClicked()
GlideApp.with(this).clear(blurHashView)
blurHashView.setImageDrawable(null)
hide()
}
2022-10-27 16:43:52 +00:00
setOnClickListener { }
}
fun setBlurHash(blurHash: BlurHash?) {
if (isRenderEffectSupported() || callback?.userHasSeenFirstNavigationView() == true) {
return
}
if (blurHash == null) {
blurHashView.visible = false
overlayView.visible = true
overlayView.setImageDrawable(ColorDrawable(Color.argb(NO_BLUR_ALPHA, 0, 0, 0)))
GlideApp.with(this).clear(blurHashView)
return
} else {
blurHashView.visible = true
overlayView.visible = true
overlayView.setImageDrawable(ColorDrawable(Color.argb(BLUR_ALPHA, 0, 0, 0)))
}
GlideApp.with(this)
.load(blurHash)
.addListener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
setBlurHash(null)
return false
}
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
return false
}
})
.into(blurHashView)
}
fun show() {
if (callback?.userHasSeenFirstNavigationView() == true) {
return
}
visible = true
2022-10-27 16:43:52 +00:00
startLottieAnimations()
}
fun hide() {
visible = false
2022-10-27 16:43:52 +00:00
endLottieAnimations()
}
private fun startLottieAnimations() {
if (ContextUtil.getAnimationScale(context) == 0f) {
return
}
2022-10-27 16:43:52 +00:00
isPlayingAnimations = true
tapToAdvance.addAnimatorListener(object : AnimatorListenerAdapter() {
2023-01-13 14:53:44 +00:00
override fun onAnimationEnd(animation: Animator) {
2022-10-27 16:43:52 +00:00
if (isPlayingAnimations) {
swipeUp.playAnimation()
}
}
})
swipeUp.addAnimatorListener(object : AnimatorListenerAdapter() {
2023-01-13 14:53:44 +00:00
override fun onAnimationEnd(animation: Animator) {
2022-10-27 16:43:52 +00:00
if (isPlayingAnimations) {
swipeRight.playAnimation()
}
}
})
swipeRight.addAnimatorListener(object : AnimatorListenerAdapter() {
2023-01-13 14:53:44 +00:00
override fun onAnimationEnd(animation: Animator) {
2022-10-27 16:43:52 +00:00
postDelayed({
if (isPlayingAnimations) {
startLottieAnimations()
}
}, 300)
}
})
tapToAdvance.playAnimation()
}
private fun endLottieAnimations() {
isPlayingAnimations = false
}
private fun isRenderEffectSupported(): Boolean {
return Build.VERSION.SDK_INT >= 31
}
interface Callback {
fun userHasSeenFirstNavigationView(): Boolean
fun onGotItClicked()
2022-10-27 16:43:52 +00:00
fun onCloseClicked()
}
}