Reimplement main activity toolbars in compose.

This commit is contained in:
Alex Hart
2025-03-28 14:34:04 -03:00
committed by Greyson Parrelli
parent 5f7ce0d96d
commit f1985cf506
24 changed files with 1405 additions and 680 deletions

View File

@@ -3,9 +3,6 @@ package org.thoughtcrime.securesms.calls.log
import android.annotation.SuppressLint
import android.content.res.Resources
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
@@ -14,7 +11,6 @@ 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.activityViewModels
@@ -38,13 +34,10 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
import org.thoughtcrime.securesms.calls.links.details.CallLinkDetailsActivity
import org.thoughtcrime.securesms.calls.new.NewCallActivity
import org.thoughtcrime.securesms.components.Material3SearchToolbar
import org.thoughtcrime.securesms.components.ProgressCardDialogFragment
import org.thoughtcrime.securesms.components.ScrollToPositionDelegate
import org.thoughtcrime.securesms.components.ViewBinderDelegate
import org.thoughtcrime.securesms.components.menu.ActionItem
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.components.settings.app.notifications.manual.NotificationProfileSelectionFragment
import org.thoughtcrime.securesms.components.settings.conversation.ConversationSettingsActivity
import org.thoughtcrime.securesms.conversation.ConversationUpdateTick
import org.thoughtcrime.securesms.conversation.SignalBottomActionBarController
@@ -57,8 +50,9 @@ import org.thoughtcrime.securesms.conversationlist.chatfilter.FilterLerp
import org.thoughtcrime.securesms.conversationlist.chatfilter.FilterPullState
import org.thoughtcrime.securesms.databinding.CallLogFragmentBinding
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.main.MainToolbarMode
import org.thoughtcrime.securesms.main.MainToolbarViewModel
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder
import org.thoughtcrime.securesms.main.SearchBinder
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.stories.tabs.ConversationListTab
import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel
@@ -82,7 +76,6 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
private var filterViewOffsetChangeListener: AppBarLayout.OnOffsetChangedListener? = null
private val viewModel: CallLogViewModel by activityViewModels()
private val binding: CallLogFragmentBinding by ViewBinderDelegate(CallLogFragmentBinding::bind) {
binding.recyclerCoordinatorAppBar.removeOnOffsetChangedListener(filterViewOffsetChangeListener)
}
@@ -95,35 +88,11 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
private lateinit var signalBottomActionBarController: SignalBottomActionBarController
private val viewModel: CallLogViewModel by activityViewModels()
private val tabsViewModel: ConversationListTabsViewModel by viewModels(ownerProducer = { requireActivity() })
private val menuProvider = object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.calls_tab_menu, menu)
}
override fun onPrepareMenu(menu: Menu) {
val isFiltered = viewModel.filterSnapshot == CallLogFilter.MISSED
menu.findItem(R.id.action_clear_missed_call_filter).isVisible = isFiltered
menu.findItem(R.id.action_filter_missed_calls).isVisible = !isFiltered
menu.findItem(R.id.action_clear_call_history).isVisible = !viewModel.isEmpty
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
when (menuItem.itemId) {
R.id.action_clear_call_history -> clearCallHistory()
R.id.action_settings -> startActivity(AppSettingsActivity.home(requireContext()))
R.id.action_notification_profile -> NotificationProfileSelectionFragment.show(parentFragmentManager)
R.id.action_filter_missed_calls -> filterMissedCalls()
R.id.action_clear_missed_call_filter -> onClearFilterClicked()
}
return true
}
}
private val mainToolbarViewModel: MainToolbarViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().addMenuProvider(menuProvider, viewLifecycleOwner)
initializeSharedElementTransition()
viewLifecycleOwner.lifecycle.addObserver(conversationUpdateTick)
@@ -131,6 +100,15 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
val callLogAdapter = CallLogAdapter(this)
disposables.bindTo(viewLifecycleOwner)
disposables += mainToolbarViewModel.getCallLogEventsFlowable().subscribeBy {
when (it) {
MainToolbarViewModel.Event.CallLog.ApplyFilter -> filterMissedCalls()
MainToolbarViewModel.Event.CallLog.ClearFilter -> onClearFilterClicked()
MainToolbarViewModel.Event.CallLog.ClearHistory -> clearCallHistory()
}
}
callLogAdapter.setPagingController(viewModel.controller)
callLogAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
@@ -163,7 +141,7 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
.subscribe { (selected, totalCount) ->
if (selected.isNotEmpty(totalCount)) {
callLogActionMode.setCount(selected.count(totalCount))
} else {
} else if (callLogActionMode.isInActionMode()) {
callLogActionMode.end()
}
}
@@ -268,19 +246,16 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
}
private fun initializeSearchAction() {
val searchBinder = requireListener<SearchBinder>()
searchBinder.getSearchAction().setOnClickListener {
searchBinder.onSearchOpened()
searchBinder.getSearchToolbar().get().setSearchInputHint(R.string.SearchToolbar_search)
searchBinder.getSearchToolbar().get().listener = object : Material3SearchToolbar.Listener {
override fun onSearchTextChange(text: String) {
viewModel.setSearchQuery(text.trim())
}
override fun onSearchClosed() {
disposables += mainToolbarViewModel.getSearchEventsFlowable().subscribeBy {
when (it) {
MainToolbarViewModel.Event.Search.Close -> {
viewModel.setSearchQuery("")
searchBinder.onSearchClosed()
}
MainToolbarViewModel.Event.Search.Open -> {
mainToolbarViewModel.setSearchHint(R.string.SearchToolbar_search)
}
is MainToolbarViewModel.Event.Search.Query -> {
viewModel.setSearchQuery(it.query.trim())
}
}
}
@@ -294,6 +269,7 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
when (state) {
FilterPullState.CLOSING -> {
viewModel.setFilter(CallLogFilter.ALL)
mainToolbarViewModel.setCallLogFilter(CallLogFilter.ALL)
binding.recycler.doAfterNextLayout {
scrollToPositionDelegate.resetScrollPosition()
}
@@ -302,6 +278,7 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
FilterPullState.OPENING -> {
ViewUtil.setMinimumHeight(collapsingToolbarLayout, openHeight)
viewModel.setFilter(CallLogFilter.MISSED)
mainToolbarViewModel.setCallLogFilter(CallLogFilter.MISSED)
}
FilterPullState.OPEN_APEX -> if (source === ConversationFilterSource.DRAG) {
@@ -438,16 +415,15 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
private fun closeSearchIfOpen(): Boolean {
if (isSearchOpen()) {
requireListener<SearchBinder>().getSearchToolbar().get().collapse()
requireListener<SearchBinder>().onSearchClosed()
mainToolbarViewModel.setToolbarMode(MainToolbarMode.FULL)
tabsViewModel.onSearchClosed()
return true
}
return false
}
private fun isSearchVisible(): Boolean {
return requireListener<SearchBinder>().getSearchToolbar().resolved() &&
requireListener<SearchBinder>().getSearchToolbar().get().visibility == View.VISIBLE
return mainToolbarViewModel.state.value.mode == MainToolbarMode.SEARCH
}
private fun performDeletion(count: Int, callLogStagedDeletion: CallLogStagedDeletion) {