Skip to content

Commit 0964ef3

Browse files
Merge pull request #1706 from Infomaniak/remove-slidingPaneLayout
Fix Messages blink by removing SlidingPaneLayout
2 parents 3788424 + cd4b9e4 commit 0964ef3

File tree

15 files changed

+133
-237
lines changed

15 files changed

+133
-237
lines changed

app/build.gradle

-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ dependencies {
9090
implementation libs.lottie
9191
implementation libs.dragdropswipe.recyclerview
9292
implementation libs.dotsindicator
93-
implementation libs.slidingpanelayout
9493

9594
implementation libs.flexbox
9695
implementation libs.lifecycle.process

app/src/main/java/com/infomaniak/mail/ui/main/NoAnimSlidingPaneLayout.kt

-99
This file was deleted.

app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListFragment.kt

+9-3
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ import android.transition.TransitionManager
2424
import android.view.LayoutInflater
2525
import android.view.View
2626
import android.view.ViewGroup
27+
import androidx.annotation.ColorRes
2728
import androidx.annotation.DrawableRes
2829
import androidx.annotation.StringRes
2930
import androidx.appcompat.content.res.AppCompatResources.getDrawable
3031
import androidx.core.app.NotificationManagerCompat
3132
import androidx.core.view.isGone
3233
import androidx.core.view.isVisible
34+
import androidx.fragment.app.FragmentContainerView
3335
import androidx.fragment.app.viewModels
3436
import androidx.lifecycle.distinctUntilChanged
3537
import androidx.navigation.fragment.findNavController
@@ -63,7 +65,6 @@ import com.infomaniak.mail.data.models.thread.Thread.ThreadFilter
6365
import com.infomaniak.mail.databinding.FragmentThreadListBinding
6466
import com.infomaniak.mail.ui.MainActivity
6567
import com.infomaniak.mail.ui.alertDialogs.DescriptionAlertDialog
66-
import com.infomaniak.mail.ui.main.NoAnimSlidingPaneLayout
6768
import com.infomaniak.mail.ui.main.SnackbarManager
6869
import com.infomaniak.mail.ui.main.settings.swipe.SwipeActionsSettingsFragment
6970
import com.infomaniak.mail.ui.main.thread.ThreadFragment
@@ -94,8 +95,6 @@ class ThreadListFragment : TwoPaneFragment(), SwipeRefreshLayout.OnRefreshListen
9495
private val navigationArgs: ThreadListFragmentArgs by navArgs()
9596
private val threadListViewModel: ThreadListViewModel by viewModels()
9697

97-
override val slidingPaneLayout: NoAnimSlidingPaneLayout get() = binding.threadListSlidingPaneLayout
98-
9998
private val threadListMultiSelection by lazy { ThreadListMultiSelection() }
10099

101100
private var lastUpdatedDate: Date? = null
@@ -169,6 +168,13 @@ class ThreadListFragment : TwoPaneFragment(), SwipeRefreshLayout.OnRefreshListen
169168
observeUpdateInstall()
170169
}.getOrDefault(Unit)
171170

171+
@ColorRes
172+
override fun getStatusBarColor(): Int = R.color.backgroundHeaderColor
173+
174+
override fun getLeftPane(): View? = _binding?.threadsConstraintLayout
175+
176+
override fun getRightPane(): FragmentContainerView? = _binding?.threadHostFragment
177+
172178
override fun getAnchor(): View? {
173179
return if (isOnlyRightShown()) {
174180
_binding?.threadHostFragment?.getFragment<ThreadFragment?>()?.getAnchor()

app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneFragment.kt

+72-61
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ package com.infomaniak.mail.ui.main.folder
2020
import android.content.res.Configuration
2121
import android.os.Bundle
2222
import android.view.View
23+
import androidx.annotation.ColorRes
24+
import androidx.core.content.res.ResourcesCompat
25+
import androidx.core.view.isGone
26+
import androidx.core.view.isVisible
2327
import androidx.fragment.app.Fragment
28+
import androidx.fragment.app.FragmentContainerView
2429
import androidx.fragment.app.activityViewModels
2530
import androidx.navigation.fragment.findNavController
26-
import androidx.slidingpanelayout.widget.SlidingPaneLayout
2731
import com.infomaniak.lib.core.utils.getBackNavigationResult
2832
import com.infomaniak.lib.core.utils.safeNavigate
2933
import com.infomaniak.mail.MatomoMail.OPEN_FROM_DRAFT_NAME
@@ -33,76 +37,46 @@ import com.infomaniak.mail.data.cache.mailboxContent.FolderController
3337
import com.infomaniak.mail.data.models.thread.Thread
3438
import com.infomaniak.mail.ui.MainActivity
3539
import com.infomaniak.mail.ui.MainViewModel
36-
import com.infomaniak.mail.ui.main.NoAnimSlidingPaneLayout
3740
import com.infomaniak.mail.ui.main.search.SearchFragment
3841
import com.infomaniak.mail.ui.main.thread.ThreadFragment
39-
import com.infomaniak.mail.utils.UiUtils.FULLY_SLID
40-
import com.infomaniak.mail.utils.UiUtils.progressivelyColorSystemBars
41-
import com.infomaniak.mail.utils.extensions.AttachmentExtensions
42-
import com.infomaniak.mail.utils.extensions.safeNavigateToNewMessageActivity
43-
import com.infomaniak.mail.utils.extensions.setSystemBarsColors
42+
import com.infomaniak.mail.utils.extensions.*
4443
import javax.inject.Inject
4544

4645
abstract class TwoPaneFragment : Fragment() {
4746

4847
val mainViewModel: MainViewModel by activityViewModels()
4948
protected val twoPaneViewModel: TwoPaneViewModel by activityViewModels()
5049

51-
protected abstract val slidingPaneLayout: NoAnimSlidingPaneLayout
52-
5350
// TODO: When we'll update DragDropSwipeRecyclerViewLib, we'll need to make the adapter nullable.
5451
// For now it causes a memory leak, because we can't remove the strong reference
5552
// between the ThreadList's RecyclerView and its Adapter as it throws an NPE.
5653
@Inject
5754
lateinit var threadListAdapter: ThreadListAdapter
5855

59-
private val leftStatusBarColor: Int by lazy {
60-
requireContext().getColor(if (this is ThreadListFragment) R.color.backgroundHeaderColor else R.color.backgroundColor)
61-
}
62-
private val leftNavigationBarColor: Int by lazy { requireContext().getColor(R.color.backgroundColor) }
63-
private val rightStatusBarColor: Int by lazy { requireContext().getColor(R.color.backgroundColor) }
64-
private val rightNavigationBarColor: Int by lazy { requireContext().getColor(R.color.elevatedBackground) }
65-
56+
@ColorRes
57+
abstract fun getStatusBarColor(): Int
58+
abstract fun getLeftPane(): View?
59+
abstract fun getRightPane(): FragmentContainerView?
6660
abstract fun getAnchor(): View?
6761
open fun doAfterFolderChanged() = Unit
6862

69-
fun isOnlyOneShown() = slidingPaneLayout.isSlideable
70-
fun areBothShown() = !isOnlyOneShown()
71-
fun isOnlyLeftShown() = isOnlyOneShown() && !slidingPaneLayout.isOpen
72-
fun isOnlyRightShown() = isOnlyOneShown() && slidingPaneLayout.isOpen
63+
fun isOnlyOneShown(): Boolean = isPhone() || isTabletInPortrait()
64+
fun isOnlyLeftShown(): Boolean = isOnlyOneShown() && !twoPaneViewModel.isThreadOpen
65+
fun isOnlyRightShown(): Boolean = isOnlyOneShown() && twoPaneViewModel.isThreadOpen
7366

7467
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
7568
super.onViewCreated(view, savedInstanceState)
76-
setupSlidingPane()
69+
updateTwoPaneVisibilities()
7770
observeCurrentFolder()
7871
observeThreadUid()
7972
observeThreadNavigation()
8073
}
8174

8275
override fun onConfigurationChanged(newConfig: Configuration) {
8376
super.onConfigurationChanged(newConfig)
77+
updateTwoPaneVisibilities()
8478
updateDrawerLockMode()
85-
ensureThreadIsDisplayed(newConfig.orientation)
86-
}
87-
88-
private fun setupSlidingPane() = with(slidingPaneLayout) {
89-
90-
lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
91-
92-
addPanelSlideListener(object : SlidingPaneLayout.PanelSlideListener {
93-
override fun onPanelOpened(panel: View) = Unit
94-
override fun onPanelClosed(panel: View) = Unit
95-
96-
override fun onPanelSlide(panel: View, slideOffset: Float) {
97-
requireActivity().window.progressivelyColorSystemBars(
98-
slideOffset = FULLY_SLID - slideOffset,
99-
statusBarColorFrom = leftStatusBarColor,
100-
statusBarColorTo = rightStatusBarColor,
101-
navBarColorFrom = leftNavigationBarColor,
102-
navBarColorTo = rightNavigationBarColor,
103-
)
104-
}
105-
})
79+
updateStatusBarColor()
10680
}
10781

10882
private fun observeCurrentFolder() = with(twoPaneViewModel) {
@@ -128,13 +102,11 @@ abstract class TwoPaneFragment : Fragment() {
128102

129103
private fun observeThreadUid() {
130104
twoPaneViewModel.currentThreadUid.observe(viewLifecycleOwner) { threadUid ->
105+
updateTwoPaneVisibilities()
106+
updateDrawerLockMode()
131107
val isOpeningThread = threadUid != null
132108
if (isOpeningThread) {
133-
val hasOpened = slidingPaneLayout.openPaneNoAnimation()
134-
if (hasOpened) {
135-
updateDrawerLockMode()
136-
setSystemBarsColors(statusBarColor = R.color.backgroundColor, navigationBarColor = null)
137-
}
109+
if (isOnlyRightShown()) setSystemBarsColors(statusBarColor = R.color.backgroundColor, navigationBarColor = null)
138110
} else {
139111
resetPanes()
140112
}
@@ -172,33 +144,72 @@ abstract class TwoPaneFragment : Fragment() {
172144

173145
private fun resetPanes() {
174146

175-
val hasClosed = slidingPaneLayout.closePaneNoAnimation()
176-
updateDrawerLockMode()
177-
178-
if (hasClosed) {
179-
setSystemBarsColors(
180-
statusBarColor = if (this@TwoPaneFragment is ThreadListFragment) R.color.backgroundHeaderColor else null,
181-
navigationBarColor = R.color.backgroundColor,
182-
)
147+
if (isOnlyLeftShown()) {
148+
setSystemBarsColors(statusBarColor = getStatusBarColor(), navigationBarColor = R.color.backgroundColor)
183149
}
184150

185151
threadListAdapter.selectNewThread(newPosition = null, threadUid = null)
186152

187153
childFragmentManager.beginTransaction().replace(R.id.threadHostFragment, ThreadFragment()).commit()
188154
}
189155

156+
private fun updateTwoPaneVisibilities() {
157+
158+
val (leftWidth, rightWidth) = computeTwoPaneWidths(
159+
widthPixels = requireActivity().application.resources.displayMetrics.widthPixels,
160+
isThreadOpen = twoPaneViewModel.isThreadOpen,
161+
)
162+
163+
getLeftPane()?.let { leftPane ->
164+
if (leftWidth == 0) {
165+
leftPane.isGone = true
166+
} else {
167+
if (leftPane.width != leftWidth) leftPane.layoutParams?.width = leftWidth
168+
leftPane.isVisible = true
169+
}
170+
}
171+
172+
getRightPane()?.let { rightPane ->
173+
if (rightWidth == 0) {
174+
rightPane.isGone = true
175+
} else {
176+
if (rightPane.width != rightWidth) rightPane.layoutParams?.width = rightWidth
177+
rightPane.isVisible = true
178+
}
179+
}
180+
}
181+
182+
private fun computeTwoPaneWidths(widthPixels: Int, isThreadOpen: Boolean): Pair<Int, Int> = with(twoPaneViewModel) {
183+
184+
val leftPaneWidthRatio = ResourcesCompat.getFloat(resources, R.dimen.leftPaneWidthRatio)
185+
val rightPaneWidthRatio = ResourcesCompat.getFloat(resources, R.dimen.rightPaneWidthRatio)
186+
187+
return if (isTabletInLandscape()) {
188+
(leftPaneWidthRatio * widthPixels).toInt() to (rightPaneWidthRatio * widthPixels).toInt()
189+
} else {
190+
if (isThreadOpen) 0 to widthPixels else widthPixels to 0
191+
}
192+
}
193+
190194
// TODO: When we'll add the feature of swiping between Threads, we'll need to check if this function is still needed.
191195
private fun updateDrawerLockMode() {
192196
if (this is ThreadListFragment) {
193-
(requireActivity() as MainActivity).setDrawerLockMode(
194-
isLocked = twoPaneViewModel.isInThreadInPhoneMode(requireContext()),
195-
)
197+
(requireActivity() as MainActivity).setDrawerLockMode(isLocked = isOnlyRightShown())
196198
}
197199
}
198200

199-
private fun ensureThreadIsDisplayed(orientation: Int) {
200-
if (orientation == Configuration.ORIENTATION_PORTRAIT && twoPaneViewModel.isInThreadInPhoneMode(requireContext())) {
201-
slidingPaneLayout.openPaneNoAnimation()
201+
private fun updateStatusBarColor() {
202+
203+
val statusBarColor = if (isOnlyRightShown()) { // Thread (in Phone mode)
204+
if (getRightPane()?.getFragment<ThreadFragment?>()?.isScrolledToTheTop() == true) {
205+
R.color.toolbarLoweredColor
206+
} else {
207+
R.color.toolbarElevatedColor
208+
}
209+
} else { // ThreadList or Search
210+
getStatusBarColor()
202211
}
212+
213+
setSystemBarsColors(statusBarColor = statusBarColor, navigationBarColor = null)
203214
}
204215
}

app/src/main/java/com/infomaniak/mail/ui/main/folder/TwoPaneViewModel.kt

-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818
package com.infomaniak.mail.ui.main.folder
1919

20-
import android.content.Context
2120
import android.net.Uri
2221
import android.os.Bundle
2322
import androidx.annotation.IdRes
@@ -32,7 +31,6 @@ import com.infomaniak.mail.data.models.message.Message
3231
import com.infomaniak.mail.data.models.thread.Thread
3332
import com.infomaniak.mail.ui.newMessage.NewMessageActivityArgs
3433
import com.infomaniak.mail.utils.Utils.runCatchingRealm
35-
import com.infomaniak.mail.utils.extensions.canDisplayOnlyOnePane
3634
import dagger.hilt.android.lifecycle.HiltViewModel
3735
import javax.inject.Inject
3836

@@ -94,8 +92,6 @@ class TwoPaneViewModel @Inject constructor(
9492
)
9593
}
9694

97-
fun isInThreadInPhoneMode(context: Context): Boolean = isThreadOpen && context.canDisplayOnlyOnePane()
98-
9995
data class NavData(
10096
@IdRes val resId: Int,
10197
val args: Bundle,

0 commit comments

Comments
 (0)