mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
Showing storage selection dialog at first time when copying/moving ZIM file
This commit is contained in:
parent
9c6267d05f
commit
bd45f0e942
@ -30,6 +30,11 @@ import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.net.toUri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import eu.mhutti1.utils.storage.STORAGE_SELECT_STORAGE_TITLE_TEXTVIEW_SIZE
|
||||
import eu.mhutti1.utils.storage.StorageDevice
|
||||
import eu.mhutti1.utils.storage.StorageDeviceUtils
|
||||
import eu.mhutti1.utils.storage.StorageSelectDialog
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -43,6 +48,8 @@ import org.kiwix.kiwixmobile.core.extensions.deleteFile
|
||||
import org.kiwix.kiwixmobile.core.extensions.isFileExist
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
|
||||
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
|
||||
import org.kiwix.kiwixmobile.core.utils.EXTERNAL_SELECT_POSITION
|
||||
import org.kiwix.kiwixmobile.core.utils.INTERNAL_SELECT_POSITION
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
|
||||
@ -74,6 +81,10 @@ class CopyMoveFileHandler @Inject constructor(
|
||||
var isMoveOperation = false
|
||||
var shouldValidateZimFile: Boolean = false
|
||||
private var fileSystemDisposable: Disposable? = null
|
||||
private lateinit var fragmentManager: FragmentManager
|
||||
private val storageDeviceList by lazy {
|
||||
StorageDeviceUtils.getWritableStorage(activity)
|
||||
}
|
||||
|
||||
private val copyMoveTitle: String by lazy {
|
||||
if (isMoveOperation) {
|
||||
@ -93,13 +104,24 @@ class CopyMoveFileHandler @Inject constructor(
|
||||
fun showMoveFileToPublicDirectoryDialog(
|
||||
uri: Uri? = null,
|
||||
documentFile: DocumentFile? = null,
|
||||
shouldValidateZimFile: Boolean = false
|
||||
shouldValidateZimFile: Boolean = false,
|
||||
fragmentManager: FragmentManager
|
||||
) {
|
||||
this.shouldValidateZimFile = shouldValidateZimFile
|
||||
this.fragmentManager = fragmentManager
|
||||
setSelectedFileAndUri(uri, documentFile)
|
||||
if (!sharedPreferenceUtil.copyMoveZimFilePermissionDialog) {
|
||||
showMoveToPublicDirectoryPermissionDialog()
|
||||
if (sharedPreferenceUtil.shouldShowStorageSelectionDialog && storageDeviceList.size > 1) {
|
||||
// Show dialog to select storage if more than one storage device is available, and user
|
||||
// have not configured the storage yet.
|
||||
showCopyMoveDialog(true)
|
||||
} else {
|
||||
if (storageDeviceList.size == 1) {
|
||||
// If only internal storage is currently available, set shouldShowStorageSelectionDialog
|
||||
// to true. This allows the storage configuration dialog to be shown again if the
|
||||
// user removes an external storage device (like an SD card) and then reinserts it.
|
||||
// This ensures they are prompted to configure storage settings upon SD card reinsertion.
|
||||
sharedPreferenceUtil.shouldShowStorageSelectionDialog = true
|
||||
}
|
||||
if (validateZimFileCanCopyOrMove()) {
|
||||
showCopyMoveDialog()
|
||||
}
|
||||
@ -107,8 +129,8 @@ class CopyMoveFileHandler @Inject constructor(
|
||||
}
|
||||
|
||||
fun setSelectedFileAndUri(uri: Uri?, documentFile: DocumentFile?) {
|
||||
selectedFileUri = uri
|
||||
selectedFile = documentFile
|
||||
uri?.let { selectedFileUri = it }
|
||||
documentFile?.let { selectedFile = it }
|
||||
}
|
||||
|
||||
fun setFileCopyMoveCallback(fileCopyMoveCallback: FileCopyMoveCallback?) {
|
||||
@ -119,23 +141,35 @@ class CopyMoveFileHandler @Inject constructor(
|
||||
lifecycleScope = coroutineScope
|
||||
}
|
||||
|
||||
private fun showMoveToPublicDirectoryPermissionDialog() {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.MoveFileToPublicDirectoryPermissionDialog,
|
||||
{
|
||||
sharedPreferenceUtil.copyMoveZimFilePermissionDialog = true
|
||||
private fun showStorageSelectDialog() = StorageSelectDialog()
|
||||
.apply {
|
||||
onSelectAction = ::copyMoveZIMFileInSelectedStorage
|
||||
titleSize = STORAGE_SELECT_STORAGE_TITLE_TEXTVIEW_SIZE
|
||||
setStorageDeviceList(storageDeviceList)
|
||||
setShouldShowCheckboxSelected(false)
|
||||
}
|
||||
.show(
|
||||
fragmentManager,
|
||||
activity.getString(R.string.choose_storage_to_copy_move_zim_file)
|
||||
)
|
||||
|
||||
fun copyMoveZIMFileInSelectedStorage(storageDevice: StorageDevice) {
|
||||
sharedPreferenceUtil.apply {
|
||||
shouldShowStorageSelectionDialog = false
|
||||
putPrefStorage(sharedPreferenceUtil.getPublicDirectoryPath(storageDevice.name))
|
||||
putStoragePosition(
|
||||
if (storageDevice.isInternal) INTERNAL_SELECT_POSITION
|
||||
else EXTERNAL_SELECT_POSITION
|
||||
)
|
||||
}
|
||||
if (validateZimFileCanCopyOrMove()) {
|
||||
if (isMoveOperation) {
|
||||
performMoveOperation()
|
||||
} else {
|
||||
performCopyOperation()
|
||||
}
|
||||
},
|
||||
{
|
||||
sharedPreferenceUtil.copyMoveZimFilePermissionDialog = true
|
||||
if (validateZimFileCanCopyOrMove()) {
|
||||
performMoveOperation()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun isBookLessThan4GB(): Boolean =
|
||||
(selectedFile?.length() ?: 0L) < FOUR_GIGABYTES_IN_KILOBYTES
|
||||
@ -192,23 +226,31 @@ class CopyMoveFileHandler @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun showCopyMoveDialog() {
|
||||
fun showCopyMoveDialog(showStorageSelectionDialog: Boolean = false) {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.CopyMoveFileToPublicDirectoryDialog,
|
||||
::performCopyOperation,
|
||||
::performMoveOperation
|
||||
{ performCopyOperation(showStorageSelectionDialog) },
|
||||
{ performMoveOperation(showStorageSelectionDialog) }
|
||||
)
|
||||
}
|
||||
|
||||
fun performCopyOperation() {
|
||||
fun performCopyOperation(showStorageSelectionDialog: Boolean = false) {
|
||||
isMoveOperation = false
|
||||
if (showStorageSelectionDialog) {
|
||||
showStorageSelectDialog()
|
||||
} else {
|
||||
copyZimFileToPublicAppDirectory()
|
||||
}
|
||||
}
|
||||
|
||||
fun performMoveOperation() {
|
||||
fun performMoveOperation(showStorageSelectionDialog: Boolean = false) {
|
||||
isMoveOperation = true
|
||||
if (showStorageSelectionDialog) {
|
||||
showStorageSelectDialog()
|
||||
} else {
|
||||
moveZimFileToPublicAppDirectory()
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyZimFileToPublicAppDirectory() {
|
||||
lifecycleScope?.launch {
|
||||
|
@ -431,7 +431,8 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
uri,
|
||||
documentFile,
|
||||
// pass if fileName is null then we will validate it after copying/moving
|
||||
fileName == null
|
||||
fileName == null,
|
||||
parentFragmentManager
|
||||
)
|
||||
} else {
|
||||
getZimFileFromUri(uri)?.let(::navigateToReaderFragment)
|
||||
@ -669,6 +670,7 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
.apply {
|
||||
onSelectAction = ::storeDeviceInPreferences
|
||||
setStorageDeviceList(storageDeviceList)
|
||||
setShouldShowCheckboxSelected(true)
|
||||
}
|
||||
.show(parentFragmentManager, getString(string.pref_storage))
|
||||
|
||||
@ -683,6 +685,6 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
else EXTERNAL_SELECT_POSITION
|
||||
)
|
||||
// after selecting the storage try to copy/move the zim file.
|
||||
copyMoveFileHandler?.showMoveFileToPublicDirectoryDialog()
|
||||
copyMoveFileHandler?.copyMoveZIMFileInSelectedStorage(storageDevice)
|
||||
}
|
||||
}
|
||||
|
@ -577,6 +577,7 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
onSelectAction = ::storeDeviceInPreferences
|
||||
titleSize = STORAGE_SELECT_STORAGE_TITLE_TEXTVIEW_SIZE
|
||||
setStorageDeviceList(storageDeviceList)
|
||||
setShouldShowCheckboxSelected(false)
|
||||
}
|
||||
.show(parentFragmentManager, getString(string.choose_storage_to_download_book))
|
||||
|
||||
|
@ -230,15 +230,15 @@ class CopyMoveFileHandlerTest {
|
||||
|
||||
fileHandler.showMoveFileToPublicDirectoryDialog()
|
||||
every { fileHandler.validateZimFileCanCopyOrMove() } returns true
|
||||
every { fileHandler.performCopyOperation() } just Runs
|
||||
every { fileHandler.performCopyOperation(showStorageSelectionDialog) } just Runs
|
||||
|
||||
positiveButtonClickSlot.captured.invoke()
|
||||
verify { fileHandler.performCopyOperation() }
|
||||
verify { fileHandler.performCopyOperation(showStorageSelectionDialog) }
|
||||
every { sharedPreferenceUtil.copyMoveZimFilePermissionDialog } returns false
|
||||
every { fileHandler.performMoveOperation() } just Runs
|
||||
every { fileHandler.performMoveOperation(showStorageSelectionDialog) } just Runs
|
||||
negativeButtonClickSlot.captured.invoke()
|
||||
|
||||
verify { fileHandler.performMoveOperation() }
|
||||
verify { fileHandler.performMoveOperation(showStorageSelectionDialog) }
|
||||
|
||||
verify { sharedPreferenceUtil.copyMoveZimFilePermissionDialog = true }
|
||||
}
|
||||
@ -275,14 +275,14 @@ class CopyMoveFileHandlerTest {
|
||||
|
||||
every { fileHandler.validateZimFileCanCopyOrMove() } returns true
|
||||
fileHandler.showMoveFileToPublicDirectoryDialog()
|
||||
every { fileHandler.performCopyOperation() } just Runs
|
||||
every { fileHandler.performCopyOperation(showStorageSelectionDialog) } just Runs
|
||||
|
||||
positiveButtonClickSlot.captured.invoke()
|
||||
verify { fileHandler.performCopyOperation() }
|
||||
every { fileHandler.performMoveOperation() } just Runs
|
||||
verify { fileHandler.performCopyOperation(showStorageSelectionDialog) }
|
||||
every { fileHandler.performMoveOperation(showStorageSelectionDialog) } just Runs
|
||||
negativeButtonClickSlot.captured.invoke()
|
||||
|
||||
verify { fileHandler.performMoveOperation() }
|
||||
verify { fileHandler.performMoveOperation(showStorageSelectionDialog) }
|
||||
}
|
||||
|
||||
private fun prepareFileSystemAndFileForMockk(
|
||||
|
@ -50,13 +50,14 @@ class StorageSelectDialog : DialogFragment() {
|
||||
private var aTitle: String? = null
|
||||
private var storageSelectDialogViewBinding: StorageSelectDialogBinding? = null
|
||||
private val storageDeviceList = arrayListOf<StorageDevice>()
|
||||
private var shouldShowCheckboxSelected: Boolean = true
|
||||
|
||||
private val storageAdapter: StorageAdapter by lazy {
|
||||
StorageAdapter(
|
||||
StorageDelegate(
|
||||
storageCalculator,
|
||||
sharedPreferenceUtil,
|
||||
aTitle == getString(R.string.choose_storage_to_download_book)
|
||||
shouldShowCheckboxSelected
|
||||
) {
|
||||
onSelectAction?.invoke(it)
|
||||
dismiss()
|
||||
@ -68,6 +69,10 @@ class StorageSelectDialog : DialogFragment() {
|
||||
this.storageDeviceList.addAll(storageDeviceList)
|
||||
}
|
||||
|
||||
fun setShouldShowCheckboxSelected(shouldShowCheckboxSelected: Boolean) {
|
||||
this.shouldShowCheckboxSelected = shouldShowCheckboxSelected
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
@ -30,7 +30,7 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
class StorageDelegate(
|
||||
private val storageCalculator: StorageCalculator,
|
||||
private val sharedPreferenceUtil: SharedPreferenceUtil,
|
||||
private val isShowingStorageOptionForFirstDownload: Boolean,
|
||||
private val shouldShowCheckboxSelected: Boolean,
|
||||
private val onClickAction: (StorageDevice) -> Unit
|
||||
) : AdapterDelegate<StorageDevice> {
|
||||
override fun createViewHolder(parent: ViewGroup): ViewHolder {
|
||||
@ -38,7 +38,7 @@ class StorageDelegate(
|
||||
parent.viewBinding(ItemStoragePreferenceBinding::inflate, false),
|
||||
storageCalculator,
|
||||
sharedPreferenceUtil,
|
||||
isShowingStorageOptionForFirstDownload,
|
||||
shouldShowCheckboxSelected,
|
||||
onClickAction
|
||||
)
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ internal class StorageViewHolder(
|
||||
private val itemStoragePreferenceBinding: ItemStoragePreferenceBinding,
|
||||
private val storageCalculator: StorageCalculator,
|
||||
private val sharedPreferenceUtil: SharedPreferenceUtil,
|
||||
private val isShowingStorageOptionForFirstDownload: Boolean,
|
||||
private val shouldShowCheckboxSelected: Boolean,
|
||||
private val onClickAction: (StorageDevice) -> Unit
|
||||
) : BaseViewHolder<StorageDevice>(itemStoragePreferenceBinding.root) {
|
||||
|
||||
@ -60,7 +60,7 @@ internal class StorageViewHolder(
|
||||
)
|
||||
)
|
||||
|
||||
radioButton.isChecked = !isShowingStorageOptionForFirstDownload &&
|
||||
radioButton.isChecked = shouldShowCheckboxSelected &&
|
||||
adapterPosition == sharedPreferenceUtil.storagePosition
|
||||
freeSpace.apply {
|
||||
text = item.getFreeSpace(root.context, storageCalculator)
|
||||
|
@ -257,11 +257,11 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
||||
_textZooms.offer(textZoom)
|
||||
}
|
||||
|
||||
var copyMoveZimFilePermissionDialog: Boolean
|
||||
get() = sharedPreferences.getBoolean(PREF_COPY_MOVE_PERMISSION, false)
|
||||
var shouldShowStorageSelectionDialog: Boolean
|
||||
get() = sharedPreferences.getBoolean(PREF_SHOW_COPY_MOVE_STORAGE_SELECTION_DIALOG, true)
|
||||
set(value) {
|
||||
sharedPreferences.edit {
|
||||
putBoolean(PREF_COPY_MOVE_PERMISSION, value)
|
||||
putBoolean(PREF_SHOW_COPY_MOVE_STORAGE_SELECTION_DIALOG, value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,7 +329,7 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
||||
const val PREF_HISTORY_MIGRATED = "pref_history_migrated"
|
||||
const val PREF_NOTES_MIGRATED = "pref_notes_migrated"
|
||||
const val PREF_APP_DIRECTORY_TO_PUBLIC_MIGRATED = "pref_app_directory_to_public_migrated"
|
||||
const val PREF_COPY_MOVE_PERMISSION = "pref_copy_move_permission"
|
||||
const val PREF_SHOW_COPY_MOVE_STORAGE_SELECTION_DIALOG = "pref_show_copy_move_storage_dialog"
|
||||
private const val PREF_LATER_CLICKED_MILLIS = "pref_later_clicked_millis"
|
||||
const val PREF_LAST_DONATION_POPUP_SHOWN_IN_MILLISECONDS =
|
||||
"pref_last_donation_shown_in_milliseconds"
|
||||
|
@ -123,6 +123,7 @@ sealed class KiwixDialog(
|
||||
R.string.copy_move_files_dialog_description,
|
||||
R.string.action_copy,
|
||||
R.string.move,
|
||||
neutralMessage = R.string.cancel,
|
||||
cancelable = false
|
||||
)
|
||||
|
||||
|
@ -331,6 +331,7 @@
|
||||
<string name="copy_file_error_message">Error in copying the ZIM file: %s.</string>
|
||||
<string name="move_files_permission_dialog_title">Move/Copy files to app public directory?</string>
|
||||
<string name="move_files_permission_dialog_description">Due to Google Play policies on Android 11 and above, our app can no longer directly access files stored elsewhere on your device. To let you view your selected files, we need to move or copy them into a special folder within our application directory. This allows us to access and open the files. Do you agree to this?</string>
|
||||
<string name="choose_storage_to_copy_move_zim_file">Choose storage to copy/move ZIM file</string>
|
||||
<string name="move_file_error_message">Error in moving the ZIM file: %s.</string>
|
||||
<string name="how_to_update_content">How to update content?</string>
|
||||
<string name="update_content_description">To update content (a ZIM file) you need to download the full latest version of this very same content. You can do that via the download section.</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user