Merge pull request #4088 from kiwix/Fixes#4085

Fixed: Transfer ZIM file freezes on tablet
This commit is contained in:
Kelson 2024-11-20 07:33:37 +01:00 committed by GitHub
commit 86f8432f45
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 105 additions and 42 deletions

View File

@ -147,37 +147,35 @@ class LocalFileTransferTest {
@Test @Test
fun showCaseFeature() { fun showCaseFeature() {
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.TIRAMISU) { shouldShowShowCaseFeatureToUser(true, isResetShowCaseId = true)
shouldShowShowCaseFeatureToUser(true, isResetShowCaseId = true) activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply { moveToState(Lifecycle.State.RESUMED)
moveToState(Lifecycle.State.RESUMED) onActivity {
onActivity { handleLocaleChange(
handleLocaleChange( it,
it, "en",
"en", SharedPreferenceUtil(context)
SharedPreferenceUtil(context) )
) it.navigate(R.id.libraryFragment)
it.navigate(R.id.libraryFragment)
}
} }
StandardActions.closeDrawer()
library {
assertGetZimNearbyDeviceDisplayed()
clickFileTransferIcon {
assertClickNearbyDeviceMessageVisible()
clickOnGotItButton()
assertDeviceNameMessageVisible()
clickOnGotItButton()
assertNearbyDeviceListMessageVisible()
clickOnGotItButton()
assertTransferZimFilesListMessageVisible()
clickOnGotItButton()
pressBack()
assertGetZimNearbyDeviceDisplayed()
}
}
LeakAssertions.assertNoLeaks()
} }
StandardActions.closeDrawer()
library {
assertGetZimNearbyDeviceDisplayed()
clickFileTransferIcon {
assertClickNearbyDeviceMessageVisible()
clickOnGotItButton()
assertDeviceNameMessageVisible()
clickOnGotItButton()
assertNearbyDeviceListMessageVisible()
clickOnGotItButton()
assertTransferZimFilesListMessageVisible()
clickOnGotItButton()
pressBack()
assertGetZimNearbyDeviceDisplayed()
}
}
LeakAssertions.assertNoLeaks()
} }
@Test @Test

View File

@ -36,13 +36,13 @@ import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.provider.Settings import android.provider.Settings
import org.kiwix.kiwixmobile.core.utils.files.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
@ -55,11 +55,14 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import org.kiwix.kiwixmobile.R import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.core.R.string
import org.kiwix.kiwixmobile.core.R.drawable
import org.kiwix.kiwixmobile.cachedComponent import org.kiwix.kiwixmobile.cachedComponent
import org.kiwix.kiwixmobile.core.R.dimen
import org.kiwix.kiwixmobile.core.R.drawable
import org.kiwix.kiwixmobile.core.R.string
import org.kiwix.kiwixmobile.core.base.BaseActivity import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.base.BaseFragment import org.kiwix.kiwixmobile.core.base.BaseFragment
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isLandScapeMode
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isTablet
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.popNavigationBackstack import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.popNavigationBackstack
import org.kiwix.kiwixmobile.core.extensions.getToolbarNavigationIcon import org.kiwix.kiwixmobile.core.extensions.getToolbarNavigationIcon
import org.kiwix.kiwixmobile.core.extensions.setToolTipWithContentDescription import org.kiwix.kiwixmobile.core.extensions.setToolTipWithContentDescription
@ -69,6 +72,7 @@ import org.kiwix.kiwixmobile.core.navigateToAppSettings
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
import org.kiwix.kiwixmobile.core.utils.files.Log
import org.kiwix.kiwixmobile.databinding.FragmentLocalFileTransferBinding import org.kiwix.kiwixmobile.databinding.FragmentLocalFileTransferBinding
import org.kiwix.kiwixmobile.localFileTransfer.WifiDirectManager.Companion.getDeviceStatus import org.kiwix.kiwixmobile.localFileTransfer.WifiDirectManager.Companion.getDeviceStatus
import org.kiwix.kiwixmobile.localFileTransfer.adapter.WifiP2pDelegate import org.kiwix.kiwixmobile.localFileTransfer.adapter.WifiP2pDelegate
@ -143,11 +147,42 @@ class LocalFileTransferFragment :
wifiDirectManager.callbacks = this wifiDirectManager.callbacks = this
wifiDirectManager.lifecycleCoroutineScope = lifecycleScope wifiDirectManager.lifecycleCoroutineScope = lifecycleScope
wifiDirectManager.startWifiDirectManager(filesForTransfer) wifiDirectManager.startWifiDirectManager(filesForTransfer)
fragmentLocalFileTransferBinding fragmentLocalFileTransferBinding?.apply {
?.textViewDeviceName textViewDeviceName.setToolTipWithContentDescription(getString(string.your_device))
?.setToolTipWithContentDescription(getString(string.your_device)) fileTransferShowCaseView.apply {
val fileTransferShowViewParams = layoutParams
fileTransferShowViewParams.width = getShowCaseViewWidth()
fileTransferShowViewParams.height = getShowCaseViewHeight()
layoutParams = fileTransferShowViewParams
}
nearbyDeviceShowCaseView.apply {
val nearbyDeviceShowCaseViewParams = layoutParams
nearbyDeviceShowCaseViewParams.width = getShowCaseViewWidth()
nearbyDeviceShowCaseViewParams.height = getShowCaseViewHeight()
layoutParams = nearbyDeviceShowCaseViewParams
}
}
} }
private fun getShowCaseViewWidth(): Int {
return when {
requireActivity().isTablet() -> {
requireActivity().resources.getDimensionPixelSize(dimen.maximum_donation_popup_width)
}
requireActivity().isLandScapeMode() -> {
requireActivity().resources.getDimensionPixelSize(
dimen.showcase_view_maximum_width_in_landscape_mode
)
}
else -> FrameLayout.LayoutParams.MATCH_PARENT
}
}
private fun getShowCaseViewHeight(): Int =
requireActivity().resources.getDimensionPixelSize(dimen.showcase_view_maximum_height)
private fun setupMenu() { private fun setupMenu() {
(requireActivity() as MenuHost).addMenuProvider( (requireActivity() as MenuHost).addMenuProvider(
object : MenuProvider { object : MenuProvider {
@ -193,12 +228,12 @@ class LocalFileTransferFragment :
getString(string.got_it) getString(string.got_it)
) )
addSequenceItem( addSequenceItem(
fragmentLocalFileTransferBinding?.listPeerDevices, fragmentLocalFileTransferBinding?.nearbyDeviceShowCaseView,
getString(string.nearby_devices_list_message), getString(string.nearby_devices_list_message),
getString(string.got_it) getString(string.got_it)
) )
addSequenceItem( addSequenceItem(
fragmentLocalFileTransferBinding?.recyclerViewTransferFiles, fragmentLocalFileTransferBinding?.fileTransferShowCaseView,
getString(string.transfer_zim_files_list_message), getString(string.transfer_zim_files_list_message),
getString(string.got_it) getString(string.got_it)
) )

View File

@ -35,15 +35,15 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:contentDescription="@string/device_name"
android:gravity="start|center"
android:minHeight="@dimen/material_minimum_height_and_width"
android:paddingStart="5dp" android:paddingStart="5dp"
android:paddingEnd="5dp" android:paddingEnd="5dp"
android:paddingBottom="5dp" android:paddingBottom="5dp"
android:textIsSelectable="true" android:textIsSelectable="true"
android:gravity="start|center"
android:minHeight="@dimen/material_minimum_height_and_width"
android:textSize="17sp" android:textSize="17sp"
android:textStyle="bold" android:textStyle="bold"
android:contentDescription="@string/device_name"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -98,6 +98,15 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device" /> app:layout_constraintTop_toBottomOf="@id/text_view_available_device" />
<View
android:id="@+id/nearby_device_show_case_view"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_margin="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device" />
<ProgressBar <ProgressBar
android:id="@+id/progress_bar_searching_peers" android:id="@+id/progress_bar_searching_peers"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -138,8 +147,16 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/view_file_list_boundary" /> app:layout_constraintTop_toBottomOf="@id/view_file_list_boundary" />
<View
android:id="@+id/file_transfer_show_case_view"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_margin="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_files_for_transfer" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
tools:listitem="@layout/item_transfer_list"
android:id="@+id/recycler_view_transfer_files" android:id="@+id/recycler_view_transfer_files"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
@ -148,6 +165,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_files_for_transfer" /> app:layout_constraintTop_toBottomOf="@id/text_view_files_for_transfer"
tools:listitem="@layout/item_transfer_list" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -189,4 +189,14 @@ object ActivityExtensions {
fun Activity.isLandScapeMode(): Boolean = fun Activity.isLandScapeMode(): Boolean =
resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
@Suppress("MagicNumber")
fun Activity.isTablet(): Boolean {
val configuration = resources.configuration
val isLargeOrXLarge =
configuration.screenLayout and
Configuration.SCREENLAYOUT_SIZE_MASK >= Configuration.SCREENLAYOUT_SIZE_LARGE
val isWideEnough = configuration.smallestScreenWidthDp >= 600
return isLargeOrXLarge && isWideEnough
}
} }

View File

@ -26,4 +26,6 @@
<dimen name="find_in_page_button_padding">13dp</dimen> <dimen name="find_in_page_button_padding">13dp</dimen>
<dimen name="donation_popup_bottom_margin">20dp</dimen> <dimen name="donation_popup_bottom_margin">20dp</dimen>
<dimen name="maximum_donation_popup_width">400dp</dimen> <dimen name="maximum_donation_popup_width">400dp</dimen>
<dimen name="showcase_view_maximum_width_in_landscape_mode">150dp</dimen>
<dimen name="showcase_view_maximum_height">10dp</dimen>
</resources> </resources>