From 570df9a529a4d208b2d4062a7d867dfdab310ba0 Mon Sep 17 00:00:00 2001 From: Kevin Boulongne Date: Tue, 30 Jan 2024 11:23:21 +0100 Subject: [PATCH] Fix statusBarColor in elevated state after rotation --- .../com/infomaniak/mail/ui/MainActivity.kt | 4 +++- .../mail/ui/main/folder/ThreadListFragment.kt | 2 +- .../mail/ui/main/folder/TwoPaneFragment.kt | 3 +-- .../mail/ui/main/folder/TwoPaneViewModel.kt | 5 ++++ .../mail/ui/main/thread/ThreadFragment.kt | 12 ++++++++++ .../mail/ui/newMessage/NewMessageManager.kt | 6 ++--- .../com/infomaniak/mail/utils/Extensions.kt | 24 ++++++++++++------- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/infomaniak/mail/ui/MainActivity.kt b/app/src/main/java/com/infomaniak/mail/ui/MainActivity.kt index afa9be70462..15c3665ad33 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/MainActivity.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/MainActivity.kt @@ -68,6 +68,7 @@ import com.infomaniak.mail.ui.alertDialogs.DescriptionAlertDialog import com.infomaniak.mail.ui.alertDialogs.TitleAlertDialog import com.infomaniak.mail.ui.main.SnackbarManager import com.infomaniak.mail.ui.main.folder.TwoPaneFragment +import com.infomaniak.mail.ui.main.folder.TwoPaneViewModel import com.infomaniak.mail.ui.main.menu.MenuDrawerFragment import com.infomaniak.mail.ui.newMessage.NewMessageActivity import com.infomaniak.mail.ui.sync.SyncAutoConfigActivity @@ -91,6 +92,7 @@ class MainActivity : BaseActivity() { private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) } private val mainViewModel: MainViewModel by viewModels() + private val twoPaneViewModel: TwoPaneViewModel by viewModels() private val backgroundColor: Int by lazy { getColor(R.color.backgroundColor) } private val backgroundHeaderColor: Int by lazy { getColor(R.color.backgroundHeaderColor) } @@ -447,7 +449,7 @@ class MainActivity : BaseActivity() { R.id.detailedContactBottomSheetDialog -> { val fragment = currentFragment if (fragment is TwoPaneFragment) { - val navigationBarColor = if (fragment.isThreadOpen() && !canDisplayBothPanes()) { + val navigationBarColor = if (twoPaneViewModel.isInThreadInPhoneMode(context = this)) { R.color.elevatedBackground } else { R.color.backgroundColor diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListFragment.kt b/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListFragment.kt index b1978be6672..f63bce0037c 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListFragment.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListFragment.kt @@ -232,7 +232,7 @@ class ThreadListFragment : TwoPaneFragment(), SwipeRefreshLayout.OnRefreshListen override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) - val statusBarColor = if (isThreadOpen() && !canDisplayBothPanes()) { + val statusBarColor = if (twoPaneViewModel.isInThreadInPhoneMode(requireContext())) { R.color.backgroundColor } else { R.color.backgroundHeaderColor diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneFragment.kt b/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneFragment.kt index 01aafd2739b..c0625270f70 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneFragment.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneFragment.kt @@ -68,7 +68,6 @@ abstract class TwoPaneFragment : Fragment() { fun areBothShown() = !isOnlyOneShown() fun isOnlyLeftShown() = isOnlyOneShown() && !slidingPaneLayout.isOpen fun isOnlyRightShown() = isOnlyOneShown() && slidingPaneLayout.isOpen - fun isThreadOpen() = twoPaneViewModel.currentThreadUid.value != null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -109,7 +108,7 @@ abstract class TwoPaneFragment : Fragment() { rightPaneFolderName.value = name if (folderId != previousFolderId) { - if (isThreadOpen() && previousFolderId != null) closeThread() + if (isThreadOpen && previousFolderId != null) closeThread() previousFolderId = folderId } diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneViewModel.kt b/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneViewModel.kt index fe1773d78f8..6ed72a541c1 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneViewModel.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneViewModel.kt @@ -17,6 +17,7 @@ */ package com.infomaniak.mail.ui.main.folder +import android.content.Context import android.net.Uri import android.os.Bundle import androidx.annotation.IdRes @@ -31,6 +32,7 @@ import com.infomaniak.mail.data.models.message.Message import com.infomaniak.mail.data.models.thread.Thread import com.infomaniak.mail.ui.newMessage.NewMessageActivityArgs import com.infomaniak.mail.utils.Utils.runCatchingRealm +import com.infomaniak.mail.utils.canDisplayBothPanes import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -42,6 +44,7 @@ class TwoPaneViewModel @Inject constructor( val currentThreadUid: LiveData = state.getLiveData(CURRENT_THREAD_UID_KEY) + inline val isThreadOpen get() = currentThreadUid.value != null val rightPaneFolderName = MutableLiveData() var previousFolderId: String? = null @@ -91,6 +94,8 @@ class TwoPaneViewModel @Inject constructor( ) } + fun isInThreadInPhoneMode(context: Context): Boolean = isThreadOpen && !context.canDisplayBothPanes() + data class NavData( @IdRes val resId: Int, val args: Bundle, diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt b/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt index 465e89931c3..716508d9886 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt @@ -148,6 +148,7 @@ class ThreadFragment : Fragment() { threadAdapter.reRenderMails() super.onConfigurationChanged(newConfig) updateNavigationIcon() + updateElevatedStatusBarColor() } override fun onDestroyView() { @@ -194,6 +195,17 @@ class ThreadFragment : Fragment() { } } + private fun updateElevatedStatusBarColor() { + if (twoPaneViewModel.isInThreadInPhoneMode(requireContext())) { + val statusBarColor = if (binding.messagesListNestedScrollView.isAtTheTop()) { + R.color.toolbarLoweredColor + } else { + R.color.toolbarElevatedColor + } + setSystemBarsColors(statusBarColor = statusBarColor, navigationBarColor = null) + } + } + private fun setupAdapter() = with(binding.messagesList) { adapter = ThreadAdapter( shouldLoadDistantResources = shouldLoadDistantResources(), diff --git a/app/src/main/java/com/infomaniak/mail/ui/newMessage/NewMessageManager.kt b/app/src/main/java/com/infomaniak/mail/ui/newMessage/NewMessageManager.kt index 055f58fc7ab..e538b44b265 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/newMessage/NewMessageManager.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/newMessage/NewMessageManager.kt @@ -17,7 +17,7 @@ */ package com.infomaniak.mail.ui.newMessage -import androidx.lifecycle.Lifecycle +import androidx.lifecycle.Lifecycle.Event import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import com.infomaniak.mail.databinding.FragmentNewMessageBinding @@ -55,8 +55,8 @@ abstract class NewMessageManager { } private fun onFreeReferences(setReferencesToNull: () -> Unit) { - viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _: LifecycleOwner, event: Lifecycle.Event -> - if (event == Lifecycle.Event.ON_DESTROY) setReferencesToNull() + viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _: LifecycleOwner, event: Event -> + if (event == Event.ON_DESTROY) setReferencesToNull() }) } } diff --git a/app/src/main/java/com/infomaniak/mail/utils/Extensions.kt b/app/src/main/java/com/infomaniak/mail/utils/Extensions.kt index c9fcd5a7c72..41a637d9220 100644 --- a/app/src/main/java/com/infomaniak/mail/utils/Extensions.kt +++ b/app/src/main/java/com/infomaniak/mail/utils/Extensions.kt @@ -44,7 +44,11 @@ import androidx.core.content.res.getColorOrThrow import androidx.core.text.toSpannable import androidx.core.widget.NestedScrollView import androidx.fragment.app.Fragment -import androidx.lifecycle.* +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.Lifecycle.Event +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData import androidx.navigation.NavDirections import androidx.navigation.NavOptions import androidx.navigation.fragment.findNavController @@ -107,6 +111,7 @@ import org.jsoup.nodes.Document import java.util.Calendar import java.util.Date import java.util.Scanner +import kotlin.collections.set import kotlin.math.roundToInt //region Type alias @@ -434,6 +439,8 @@ inline infix fun , V> ((E) -> V).enumValueFrom(value: V): E? return enumValues().firstOrNull { this(it) == value } } +fun View.isAtTheTop(): Boolean = !canScrollVertically(-1) + fun Fragment.changeToolbarColorOnScroll( toolbar: MaterialToolbar, nestedScrollView: NestedScrollView, @@ -444,22 +451,23 @@ fun Fragment.changeToolbarColorOnScroll( ) { var valueAnimator: ValueAnimator? = null var oldColor = requireContext().getColor(loweredColor) + var headerColorState = HeaderState.LOWERED viewLifecycleOwner.lifecycle.addObserver(object : LifecycleEventObserver { - override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { - if (event == Lifecycle.Event.ON_DESTROY) valueAnimator?.cancel() + override fun onStateChanged(source: LifecycleOwner, event: Event) { + if (event == Event.ON_DESTROY) valueAnimator?.cancel() } }) - var headerColorState = HeaderState.LOWERED nestedScrollView.setOnScrollChangeListener { view, _, _, _, _ -> - val isAtTheTop = !view.canScrollVertically(-1) - if (headerColorState == HeaderState.ELEVATED && !isAtTheTop) return@setOnScrollChangeListener + + val isAtTheTop = view.isAtTheTop() + if (!isAtTheTop && headerColorState == HeaderState.ELEVATED) return@setOnScrollChangeListener val newColor = view.context.getColor(if (isAtTheTop) loweredColor else elevatedColor) - headerColorState = if (isAtTheTop) HeaderState.LOWERED else HeaderState.ELEVATED + if (newColor == oldColor) return@setOnScrollChangeListener - if (oldColor == newColor) return@setOnScrollChangeListener + headerColorState = if (isAtTheTop) HeaderState.LOWERED else HeaderState.ELEVATED valueAnimator?.cancel() valueAnimator = UiUtils.animateColorChange(oldColor, newColor, animate = true) { color ->