diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionActivity.kt
index 27ad209f0..b9ffd8f78 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionActivity.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionActivity.kt
@@ -1,18 +1,24 @@
package org.thoughtcrime.securesms.mediasend.v2
+import android.animation.ValueAnimator
import android.content.Context
import android.content.Intent
+import android.graphics.Color
import android.os.Bundle
import android.view.KeyEvent
-import android.view.View
-import android.view.ViewGroup
+import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatDelegate
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.Navigation
import androidx.navigation.fragment.NavHostFragment
+import androidx.transition.AutoTransition
+import androidx.transition.TransitionManager
+import com.google.android.material.animation.ArgbEvaluatorCompat
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.PassphraseRequiredActivity
import org.thoughtcrime.securesms.R
@@ -43,6 +49,11 @@ class MediaSelectionActivity :
EmojiSearchFragment.Callback,
SearchConfigurationProvider {
+ private var animateInShadowLayerValueAnimator: ValueAnimator? = null
+ private var animateInTextColorValueAnimator: ValueAnimator? = null
+ private var animateOutShadowLayerValueAnimator: ValueAnimator? = null
+ private var animateOutTextColorValueAnimator: ValueAnimator? = null
+
lateinit var viewModel: MediaSelectionViewModel
private val textViewModel: TextStoryPostCreationViewModel by viewModels()
@@ -69,9 +80,16 @@ class MediaSelectionActivity :
val factory = MediaSelectionViewModel.Factory(destination, transportOption, initialMedia, message, isReply, MediaSelectionRepository(this))
viewModel = ViewModelProvider(this, factory)[MediaSelectionViewModel::class.java]
- val textStoryToggle: ViewGroup = findViewById(R.id.switch_widget)
- val textSwitch: View = findViewById(R.id.text_switch)
- val cameraSwitch: View = findViewById(R.id.camera_switch)
+ val textStoryToggle: ConstraintLayout = findViewById(R.id.switch_widget)
+ val cameraSelectedConstraintSet = ConstraintSet().apply {
+ clone(textStoryToggle)
+ }
+ val textSelectedConstraintSet = ConstraintSet().apply {
+ clone(this@MediaSelectionActivity, R.layout.media_selection_activity_text_selected_constraints)
+ }
+
+ val textSwitch: TextView = findViewById(R.id.text_switch)
+ val cameraSwitch: TextView = findViewById(R.id.camera_switch)
textSwitch.setOnClickListener {
viewModel.sendCommand(HudCommand.GoToText)
@@ -101,13 +119,17 @@ class MediaSelectionActivity :
when (d.id) {
R.id.mediaCaptureFragment -> {
textStoryToggle.visible = canDisplayStorySwitch()
- textSwitch.isSelected = false
- cameraSwitch.isSelected = true
+
+ animateTextStyling(cameraSwitch, textSwitch, 200)
+ TransitionManager.beginDelayedTransition(textStoryToggle, AutoTransition().setDuration(200))
+ cameraSelectedConstraintSet.applyTo(textStoryToggle)
}
R.id.textStoryPostCreationFragment -> {
textStoryToggle.visible = canDisplayStorySwitch()
- textSwitch.isSelected = true
- cameraSwitch.isSelected = false
+
+ animateTextStyling(textSwitch, cameraSwitch, 200)
+ TransitionManager.beginDelayedTransition(textStoryToggle, AutoTransition().setDuration(200))
+ textSelectedConstraintSet.applyTo(textStoryToggle)
}
else -> textStoryToggle.visible = false
}
@@ -116,6 +138,36 @@ class MediaSelectionActivity :
onBackPressedDispatcher.addCallback(OnBackPressed())
}
+ private fun animateTextStyling(selectedSwitch: TextView, unselectedSwitch: TextView, duration: Long) {
+ animateInShadowLayerValueAnimator?.cancel()
+ animateInTextColorValueAnimator?.cancel()
+ animateOutShadowLayerValueAnimator?.cancel()
+ animateOutTextColorValueAnimator?.cancel()
+
+ animateInShadowLayerValueAnimator = ValueAnimator.ofFloat(selectedSwitch.shadowRadius, 0f).apply {
+ this.duration = duration
+ addUpdateListener { selectedSwitch.setShadowLayer(it.animatedValue as Float, 0f, 0f, Color.BLACK) }
+ start()
+ }
+ animateInTextColorValueAnimator = ValueAnimator.ofInt(selectedSwitch.currentTextColor, Color.BLACK).apply {
+ setEvaluator(ArgbEvaluatorCompat.getInstance())
+ this.duration = duration
+ addUpdateListener { selectedSwitch.setTextColor(it.animatedValue as Int) }
+ start()
+ }
+ animateOutShadowLayerValueAnimator = ValueAnimator.ofFloat(unselectedSwitch.shadowRadius, 3f).apply {
+ this.duration = duration
+ addUpdateListener { unselectedSwitch.setShadowLayer(it.animatedValue as Float, 0f, 0f, Color.BLACK) }
+ start()
+ }
+ animateOutTextColorValueAnimator = ValueAnimator.ofInt(unselectedSwitch.currentTextColor, Color.WHITE).apply {
+ setEvaluator(ArgbEvaluatorCompat.getInstance())
+ this.duration = duration
+ addUpdateListener { unselectedSwitch.setTextColor(it.animatedValue as Int) }
+ start()
+ }
+ }
+
private fun canDisplayStorySwitch(): Boolean {
return Stories.isFeatureEnabled() &&
FeatureFlags.storiesTextPosts() &&
diff --git a/app/src/main/res/drawable/story_pill_button_background.xml b/app/src/main/res/drawable/story_pill_button_background.xml
index b793797d8..79592bac1 100644
--- a/app/src/main/res/drawable/story_pill_button_background.xml
+++ b/app/src/main/res/drawable/story_pill_button_background.xml
@@ -1,12 +1,9 @@
-
- -
-
-
-
+
-
-
-
\ No newline at end of file
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/story_pill_toggle_background.xml b/app/src/main/res/drawable/story_pill_toggle_background.xml
deleted file mode 100644
index 9b17d068f..000000000
--- a/app/src/main/res/drawable/story_pill_toggle_background.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/media_selection_activity.xml b/app/src/main/res/layout/media_selection_activity.xml
index 227efea15..20e784349 100644
--- a/app/src/main/res/layout/media_selection_activity.xml
+++ b/app/src/main/res/layout/media_selection_activity.xml
@@ -1,6 +1,7 @@
@@ -11,82 +12,54 @@
+ android:layout_marginBottom="8dp">
-
+ app:layout_constraintBottom_toBottomOf="@id/camera_switch"
+ app:layout_constraintEnd_toEndOf="@id/camera_switch"
+ app:layout_constraintStart_toStartOf="@id/camera_switch"
+ app:layout_constraintTop_toTopOf="@id/camera_switch" />
-
-
-
-
-
-
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:background="@color/red" />
-
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/media_selection_activity_text_selected_constraints.xml b/app/src/main/res/layout/media_selection_activity_text_selected_constraints.xml
new file mode 100644
index 000000000..1e31cd5ed
--- /dev/null
+++ b/app/src/main/res/layout/media_selection_activity_text_selected_constraints.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/navigation/media.xml b/app/src/main/res/navigation/media.xml
index f50374d71..c74096a94 100644
--- a/app/src/main/res/navigation/media.xml
+++ b/app/src/main/res/navigation/media.xml
@@ -15,7 +15,11 @@
app:destination="@id/mediaGalleryFragment" />
+ app:destination="@id/textStoryPostCreationFragment"
+ app:enterAnim="@anim/slide_from_end"
+ app:exitAnim="@null"
+ app:popEnterAnim="@null"
+ app:popExitAnim="@anim/slide_to_end" />
+ tools:layout="@layout/stories_text_post_creation_fragment">