mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-07-11 16:27:04 +01:00
Add fun emoji animations when selecting boost level.
This commit is contained in:
committed by
Greyson Parrelli
parent
5bb48caafd
commit
614d6ce04b
+2
-2
@@ -52,7 +52,7 @@ data class Boost(
|
||||
val selectedBoost: Boost?,
|
||||
val currency: Currency,
|
||||
override val isEnabled: Boolean,
|
||||
val onBoostClick: (Boost) -> Unit,
|
||||
val onBoostClick: (View, Boost) -> Unit,
|
||||
val isCustomAmountFocused: Boolean,
|
||||
val onCustomAmountChanged: (String) -> Unit,
|
||||
val onCustomAmountFocusChanged: (Boolean) -> Unit,
|
||||
@@ -95,7 +95,7 @@ data class Boost(
|
||||
FiatMoneyUtil.formatOptions().trimZerosAfterDecimal()
|
||||
)
|
||||
button.setOnClickListener {
|
||||
model.onBoostClick(boost)
|
||||
model.onBoostClick(it, boost)
|
||||
custom.clearFocus()
|
||||
}
|
||||
}
|
||||
|
||||
+49
-2
@@ -1,11 +1,13 @@
|
||||
package org.thoughtcrime.securesms.components.settings.app.subscription.boost
|
||||
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.signal.core.util.DimensionUnit
|
||||
import org.signal.core.util.logging.Log
|
||||
@@ -23,6 +25,7 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.models.Cu
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.util.Projection
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,13 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
||||
private val viewModel: BoostViewModel by viewModels(ownerProducer = { requireActivity() })
|
||||
private val lifecycleDisposable = LifecycleDisposable()
|
||||
|
||||
private lateinit var boost1AnimationView: LottieAnimationView
|
||||
private lateinit var boost2AnimationView: LottieAnimationView
|
||||
private lateinit var boost3AnimationView: LottieAnimationView
|
||||
private lateinit var boost4AnimationView: LottieAnimationView
|
||||
private lateinit var boost5AnimationView: LottieAnimationView
|
||||
private lateinit var boost6AnimationView: LottieAnimationView
|
||||
|
||||
private lateinit var processingDonationPaymentDialog: AlertDialog
|
||||
|
||||
private val sayThanks: CharSequence by lazy {
|
||||
@@ -58,6 +68,13 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
||||
.setCancelable(false)
|
||||
.create()
|
||||
|
||||
boost1AnimationView = requireView().findViewById(R.id.boost1_animation)
|
||||
boost2AnimationView = requireView().findViewById(R.id.boost2_animation)
|
||||
boost3AnimationView = requireView().findViewById(R.id.boost3_animation)
|
||||
boost4AnimationView = requireView().findViewById(R.id.boost4_animation)
|
||||
boost5AnimationView = requireView().findViewById(R.id.boost5_animation)
|
||||
boost6AnimationView = requireView().findViewById(R.id.boost6_animation)
|
||||
|
||||
viewModel.state.observe(viewLifecycleOwner) { state ->
|
||||
adapter.submitList(getConfiguration(state).toMappingModelList())
|
||||
}
|
||||
@@ -119,8 +136,9 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
||||
currency = state.customAmount.currency,
|
||||
isCustomAmountFocused = state.isCustomAmountFocused,
|
||||
isEnabled = state.stage == BoostState.Stage.READY,
|
||||
onBoostClick = {
|
||||
viewModel.setSelectedBoost(it)
|
||||
onBoostClick = { view, boost ->
|
||||
startAnimationAboveSelectedBoost(view)
|
||||
viewModel.setSelectedBoost(boost)
|
||||
},
|
||||
onCustomAmountChanged = {
|
||||
viewModel.setCustomAmount(it)
|
||||
@@ -196,6 +214,35 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
|
||||
}
|
||||
}
|
||||
|
||||
private fun startAnimationAboveSelectedBoost(view: View) {
|
||||
val animationView = getAnimationContainer(view)
|
||||
val viewProjection = Projection.relativeToViewRoot(view, null)
|
||||
val animationProjection = Projection.relativeToViewRoot(animationView, null)
|
||||
val viewHorizontalCenter = viewProjection.x + viewProjection.width / 2f
|
||||
val animationHorizontalCenter = animationProjection.x + animationProjection.width / 2f
|
||||
val animationBottom = animationProjection.y + animationProjection.height
|
||||
|
||||
animationView.translationY = -(animationBottom - viewProjection.y) + (viewProjection.height / 2f)
|
||||
animationView.translationX = viewHorizontalCenter - animationHorizontalCenter
|
||||
|
||||
animationView.playAnimation()
|
||||
|
||||
viewProjection.release()
|
||||
animationProjection.release()
|
||||
}
|
||||
|
||||
private fun getAnimationContainer(view: View): LottieAnimationView {
|
||||
return when (view.id) {
|
||||
R.id.boost_1 -> boost1AnimationView
|
||||
R.id.boost_2 -> boost2AnimationView
|
||||
R.id.boost_3 -> boost3AnimationView
|
||||
R.id.boost_4 -> boost4AnimationView
|
||||
R.id.boost_5 -> boost5AnimationView
|
||||
R.id.boost_6 -> boost6AnimationView
|
||||
else -> throw AssertionError()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(BoostFragment::class.java)
|
||||
}
|
||||
|
||||
@@ -98,6 +98,18 @@ public final class Projection {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "Projection{" +
|
||||
"x=" + x +
|
||||
", y=" + y +
|
||||
", width=" + width +
|
||||
", height=" + height +
|
||||
", corners=" + corners +
|
||||
", path=" + path +
|
||||
", rect=" + rect +
|
||||
'}';
|
||||
}
|
||||
|
||||
public @NonNull Projection translateX(float xTranslation) {
|
||||
return set(x + xTranslation, y, width, height, corners);
|
||||
}
|
||||
|
||||
@@ -26,4 +26,52 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/handle" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/boost1_animation"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="360dp"
|
||||
app:lottie_rawRes="@raw/boost_smile"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/boost2_animation"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="360dp"
|
||||
app:lottie_rawRes="@raw/boost_clap"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/boost3_animation"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="360dp"
|
||||
app:lottie_rawRes="@raw/boost_heart_eyes"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/boost4_animation"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="360dp"
|
||||
app:lottie_rawRes="@raw/boost_fire"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/boost5_animation"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="360dp"
|
||||
app:lottie_rawRes="@raw/boost_shock"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/boost6_animation"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="360dp"
|
||||
app:lottie_rawRes="@raw/boost_rockets"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user