mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-15 07:28:30 +00:00
Add animation when switching from chats to calls.
This commit is contained in:
@@ -11,14 +11,18 @@ import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.app.SharedElementCallback
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.kotlin.Flowables
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.signal.core.util.DimensionUnit
|
||||
@@ -52,6 +56,7 @@ import org.thoughtcrime.securesms.util.doAfterNextLayout
|
||||
import org.thoughtcrime.securesms.util.fragments.requireListener
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import java.util.Objects
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Call Log tab.
|
||||
@@ -94,6 +99,7 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
requireActivity().addMenuProvider(menuProvider, viewLifecycleOwner)
|
||||
initializeSharedElementTransition()
|
||||
|
||||
val adapter = CallLogAdapter(this)
|
||||
disposables.bindTo(viewLifecycleOwner)
|
||||
@@ -181,6 +187,26 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
|
||||
viewModel.markAllCallEventsRead()
|
||||
}
|
||||
|
||||
private fun initializeSharedElementTransition() {
|
||||
ViewCompat.setTransitionName(binding.fab, "new_convo_fab")
|
||||
ViewCompat.setTransitionName(binding.fabSharedElementTarget, "camera_fab")
|
||||
|
||||
sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.change_transform_fabs)
|
||||
setEnterSharedElementCallback(object : SharedElementCallback() {
|
||||
override fun onSharedElementStart(sharedElementNames: MutableList<String>?, sharedElements: MutableList<View>?, sharedElementSnapshots: MutableList<View>?) {
|
||||
if (sharedElementNames?.contains("camera_fab") == true) {
|
||||
this@CallLogFragment.binding.fab.setImageResource(R.drawable.symbol_edit_24)
|
||||
disposables += Single.timer(200, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy {
|
||||
this@CallLogFragment.binding.fab.setImageResource(R.drawable.symbol_phone_plus_24)
|
||||
this@CallLogFragment.binding.fabSharedElementTarget.alpha = 0f
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initializeTapToScrollToTop(scrollToPositionDelegate: ScrollToPositionDelegate) {
|
||||
disposables += tabsViewModel.tabClickEvents
|
||||
.filter { it == ConversationListTab.CALLS }
|
||||
|
||||
@@ -112,7 +112,7 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
||||
private fun goToStateFromConversationList(state: ConversationListTabsState, navController: NavController) {
|
||||
if (state.tab == ConversationListTab.CHATS) {
|
||||
return
|
||||
} else if (state.tab == ConversationListTab.STORIES) {
|
||||
} else {
|
||||
val cameraFab = requireView().findViewById<View>(R.id.camera_fab)
|
||||
val newConvoFab = requireView().findViewById<View>(R.id.fab)
|
||||
|
||||
@@ -128,19 +128,18 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
||||
)
|
||||
}
|
||||
|
||||
val destination = if (state.tab == ConversationListTab.STORIES) {
|
||||
R.id.action_conversationListFragment_to_storiesLandingFragment
|
||||
} else {
|
||||
R.id.action_conversationListFragment_to_callLogFragment
|
||||
}
|
||||
|
||||
navController.navigate(
|
||||
R.id.action_conversationListFragment_to_storiesLandingFragment,
|
||||
destination,
|
||||
null,
|
||||
null,
|
||||
extras
|
||||
)
|
||||
} else {
|
||||
navController.navigate(
|
||||
R.id.action_conversationListFragment_to_callLogFragment,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,14 +349,17 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
||||
conversationListTabsViewModel.isShowingArchived(false)
|
||||
presentToolbarForConversationListFragment()
|
||||
}
|
||||
|
||||
R.id.conversationListArchiveFragment -> {
|
||||
conversationListTabsViewModel.isShowingArchived(true)
|
||||
presentToolbarForConversationListArchiveFragment()
|
||||
}
|
||||
|
||||
R.id.storiesLandingFragment -> {
|
||||
conversationListTabsViewModel.isShowingArchived(false)
|
||||
presentToolbarForStoriesLandingFragment()
|
||||
}
|
||||
|
||||
R.id.callLogFragment -> {
|
||||
conversationListTabsViewModel.isShowingArchived(false)
|
||||
presentToolbarForCallLogFragment()
|
||||
|
||||
@@ -88,7 +88,7 @@ class ConversationListTabsViewModel(repository: ConversationListTabRepository) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T: Any> performStoreUpdate(flowable: Flowable<T>, fn: (T, ConversationListTabsState) -> ConversationListTabsState): Disposable {
|
||||
private fun <T : Any> performStoreUpdate(flowable: Flowable<T>, fn: (T, ConversationListTabsState) -> ConversationListTabsState): Disposable {
|
||||
return store.update(flowable) { t, state ->
|
||||
fn(t, state.copy(prevTab = state.tab))
|
||||
}
|
||||
|
||||
@@ -66,21 +66,48 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:contentDescription="@string/CallLogFragment__start_a_new_call"
|
||||
android:focusable="true"
|
||||
android:theme="@style/Widget.Material3.FloatingActionButton.Secondary"
|
||||
android:transitionName="new_convo_fab"
|
||||
app:backgroundTint="@color/signal_colorPrimaryContainer"
|
||||
app:shapeAppearanceOverlay="@style/Signal.ShapeOverlay.Rounded.Fab"
|
||||
app:srcCompat="@drawable/symbol_phone_plus_24"
|
||||
app:tint="@color/signal_colorOnSurface" />
|
||||
android:layout_gravity="bottom"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:layout_behavior="org.thoughtcrime.securesms.util.views.SlideUpWithSnackbarBehavior">
|
||||
|
||||
<org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton
|
||||
android:id="@+id/fab_shared_element_target"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:focusable="true"
|
||||
android:theme="@style/Widget.Material3.FloatingActionButton.Secondary"
|
||||
android:transitionName="camera_fab"
|
||||
app:shapeAppearanceOverlay="@style/Signal.ShapeOverlay.Rounded.Fab"
|
||||
app:backgroundTint="@color/signal_colorSurfaceVariant"
|
||||
app:elevation="0dp"
|
||||
app:srcCompat="@drawable/ic_camera_outline_24"
|
||||
app:tint="@color/signal_colorOnSurface" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:contentDescription="@string/CallLogFragment__start_a_new_call"
|
||||
android:focusable="true"
|
||||
android:theme="@style/Widget.Material3.FloatingActionButton.Secondary"
|
||||
android:transitionName="new_convo_fab"
|
||||
app:backgroundTint="@color/signal_colorPrimaryContainer"
|
||||
app:shapeAppearanceOverlay="@style/Signal.ShapeOverlay.Rounded.Fab"
|
||||
app:srcCompat="@drawable/symbol_phone_plus_24"
|
||||
app:tint="@color/signal_colorOnSurface" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.components.menu.SignalBottomActionBar
|
||||
android:id="@+id/bottom_action_bar"
|
||||
|
||||
Reference in New Issue
Block a user