mirror of
https://github.com/nextcloud/android.git
synced 2024-11-22 21:25:35 +03:00
Simplify ConflictResolveDialog
Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
parent
ae5064d9a5
commit
9dcdb7d05b
4 changed files with 109 additions and 89 deletions
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.utils.extensions
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
|
||||
inline fun <reified T : Parcelable> Parcel.readParcelableCompat(classLoader: ClassLoader?): T? {
|
||||
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
|
||||
readParcelable(classLoader, T::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
readParcelable(classLoader)
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
package com.owncloud.android.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
|
@ -114,33 +115,29 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
|
|||
}
|
||||
|
||||
private fun handleFolderConflict(decision: Decision) {
|
||||
offlineOperationPath?.let { path ->
|
||||
newFile?.let { serverFile ->
|
||||
val offlineOperation = fileDataStorageManager.offlineOperationDao.getByPath(path)
|
||||
val path = offlineOperationPath ?: return
|
||||
val serverFile = newFile ?: return
|
||||
val offlineOperation = fileDataStorageManager.offlineOperationDao.getByPath(path) ?: return
|
||||
|
||||
offlineOperation?.let { entity ->
|
||||
when(decision) {
|
||||
Decision.KEEP_OFFLINE_FOLDER -> {
|
||||
fileOperationsHelper?.removeFiles(listOf(serverFile), false, false)
|
||||
backgroundJobManager.startOfflineOperations()
|
||||
}
|
||||
|
||||
Decision.KEEP_SERVER_FOLDER -> {
|
||||
fileDataStorageManager.offlineOperationDao.deleteByPath(path)
|
||||
}
|
||||
|
||||
Decision.KEEP_BOTH_FOLDER -> {
|
||||
fileDataStorageManager.keepOfflineOperationAndServerFile(entity)
|
||||
backgroundJobManager.startOfflineOperations()
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
|
||||
offlineOperationNotificationManager.dismissNotification(offlineOperation.id)
|
||||
}
|
||||
when(decision) {
|
||||
Decision.KEEP_OFFLINE_FOLDER -> {
|
||||
fileOperationsHelper?.removeFiles(listOf(serverFile), false, false)
|
||||
backgroundJobManager.startOfflineOperations()
|
||||
}
|
||||
|
||||
Decision.KEEP_SERVER_FOLDER -> {
|
||||
fileDataStorageManager.offlineOperationDao.deleteByPath(path)
|
||||
}
|
||||
|
||||
Decision.KEEP_BOTH_FOLDER -> {
|
||||
fileDataStorageManager.keepOfflineOperationAndServerFile(offlineOperation)
|
||||
backgroundJobManager.startOfflineOperations()
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
|
||||
offlineOperationNotificationManager.dismissNotification(offlineOperation.id)
|
||||
}
|
||||
|
||||
private fun keepLocal(file: OCFile?, upload: OCUpload?, user: User) {
|
||||
|
@ -230,7 +227,7 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
|
|||
return
|
||||
}
|
||||
|
||||
val (ft, user) = prepareDialog()
|
||||
val (ft, _) = prepareDialog()
|
||||
val dialog = ConflictsResolveDialog.newInstance(
|
||||
this,
|
||||
offlineOperation,
|
||||
|
@ -268,6 +265,7 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CommitTransaction")
|
||||
private fun prepareDialog(): Pair<FragmentTransaction, User> {
|
||||
val userOptional = user
|
||||
if (!userOptional.isPresent) {
|
||||
|
@ -292,7 +290,7 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
|
|||
val dialog = ConflictsResolveDialog.newInstance(
|
||||
this,
|
||||
newFile!!,
|
||||
existingFile,
|
||||
existingFile!!,
|
||||
user
|
||||
)
|
||||
dialog.show(ft, "conflictDialog")
|
||||
|
|
|
@ -106,16 +106,13 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
data = savedInstanceState.getParcelableArgument(CONFLICT_DATA, ConflictDialogData::class.java)
|
||||
leftDataFile = savedInstanceState.getSerializableArgument(LEFT_FILE, File::class.java)
|
||||
rightDataFile = savedInstanceState.getParcelableArgument(RIGHT_FILE, OCFile::class.java)
|
||||
user = savedInstanceState.getParcelableArgument(USER, User::class.java)
|
||||
} else if (arguments != null) {
|
||||
data = arguments.getParcelableArgument(CONFLICT_DATA, ConflictDialogData::class.java)
|
||||
leftDataFile = arguments.getSerializableArgument(LEFT_FILE, File::class.java)
|
||||
rightDataFile = arguments.getParcelableArgument(RIGHT_FILE, OCFile::class.java)
|
||||
user = arguments.getParcelableArgument(USER, User::class.java)
|
||||
val bundle = savedInstanceState ?: arguments
|
||||
|
||||
if (bundle != null) {
|
||||
data = bundle.getParcelableArgument(ARG_CONFLICT_DATA, ConflictDialogData::class.java)
|
||||
leftDataFile = bundle.getSerializableArgument(ARG_LEFT_FILE, File::class.java)
|
||||
rightDataFile = bundle.getParcelableArgument(ARG_RIGHT_FILE, OCFile::class.java)
|
||||
user = bundle.getParcelableArgument(ARG_USER, User::class.java)
|
||||
} else {
|
||||
Toast.makeText(context, "Failed to create conflict dialog", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
@ -124,45 +121,57 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.run {
|
||||
putParcelable(CONFLICT_DATA, data)
|
||||
putParcelable(ARG_CONFLICT_DATA, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
binding = ConflictResolveDialogBinding.inflate(requireActivity().layoutInflater)
|
||||
|
||||
viewThemeUtils.platform.themeCheckbox(binding.leftCheckbox)
|
||||
viewThemeUtils.platform.themeCheckbox(binding.rightCheckbox)
|
||||
val builder = createDialogBuilder()
|
||||
|
||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
||||
setupUI()
|
||||
setOnClickListeners()
|
||||
|
||||
viewThemeUtils.run {
|
||||
platform.themeCheckbox(binding.leftCheckbox)
|
||||
platform.themeCheckbox(binding.rightCheckbox)
|
||||
dialog.colorMaterialAlertDialogBackground(requireContext(), builder)
|
||||
}
|
||||
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
private fun createDialogBuilder(): MaterialAlertDialogBuilder {
|
||||
return MaterialAlertDialogBuilder(requireContext())
|
||||
.setView(binding.root)
|
||||
.setPositiveButton(R.string.common_ok) { _: DialogInterface?, _: Int ->
|
||||
val decision = when {
|
||||
binding.leftCheckbox.isChecked && binding.rightCheckbox.isChecked ->
|
||||
if (data?.folderName == null) Decision.KEEP_BOTH_FOLDER else Decision.KEEP_BOTH
|
||||
|
||||
binding.leftCheckbox.isChecked ->
|
||||
if (data?.folderName == null) Decision.KEEP_OFFLINE_FOLDER else Decision.KEEP_LOCAL
|
||||
|
||||
binding.rightCheckbox.isChecked ->
|
||||
if (data?.folderName == null) Decision.KEEP_SERVER_FOLDER else Decision.KEEP_SERVER
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
decision?.let { listener?.conflictDecisionMade(it) }
|
||||
okButtonClick()
|
||||
}
|
||||
.setNegativeButton(R.string.common_cancel) { _: DialogInterface?, _: Int ->
|
||||
listener?.conflictDecisionMade(Decision.CANCEL)
|
||||
}
|
||||
.setTitle(data?.folderName)
|
||||
}
|
||||
|
||||
setupUI()
|
||||
setOnClickListeners()
|
||||
private fun okButtonClick() {
|
||||
binding.run {
|
||||
val isFolderNameNotExists = (data?.folderName == null)
|
||||
val decision = when {
|
||||
leftCheckbox.isChecked && rightCheckbox.isChecked ->
|
||||
if (isFolderNameNotExists) Decision.KEEP_BOTH_FOLDER else Decision.KEEP_BOTH
|
||||
|
||||
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.rightFileContainer.context, builder)
|
||||
leftCheckbox.isChecked ->
|
||||
if (isFolderNameNotExists) Decision.KEEP_OFFLINE_FOLDER else Decision.KEEP_LOCAL
|
||||
|
||||
return builder.create()
|
||||
rightCheckbox.isChecked ->
|
||||
if (isFolderNameNotExists) Decision.KEEP_SERVER_FOLDER else Decision.KEEP_SERVER
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
decision?.let { listener?.conflictDecisionMade(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupUI() {
|
||||
|
@ -284,25 +293,26 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val CONFLICT_DATA = "CONFLICT_DATA"
|
||||
private const val LEFT_FILE = "KEY_LEFT_FILE"
|
||||
private const val RIGHT_FILE = "KEY_RIGHT_FILE"
|
||||
private const val USER = "user"
|
||||
private const val ARG_CONFLICT_DATA = "CONFLICT_DATA"
|
||||
private const val ARG_LEFT_FILE = "LEFT_FILE"
|
||||
private const val ARG_RIGHT_FILE = "RIGHT_FILE"
|
||||
private const val ARG_USER = "USER"
|
||||
|
||||
@JvmStatic
|
||||
fun newInstance(
|
||||
context: Context,
|
||||
leftFile: OCFile,
|
||||
rightFile: OCFile?,
|
||||
rightFile: OCFile,
|
||||
user: User?
|
||||
): ConflictsResolveDialog {
|
||||
val file = File(leftFile.storagePath)
|
||||
val conflictData = getFileConflictData(file, rightFile, context)
|
||||
|
||||
val bundle = Bundle().apply {
|
||||
putParcelable(CONFLICT_DATA, getConflictDataForFileConflict(file, rightFile, context))
|
||||
putSerializable(LEFT_FILE, file)
|
||||
putParcelable(RIGHT_FILE, rightFile)
|
||||
putParcelable(USER, user)
|
||||
putParcelable(ARG_CONFLICT_DATA, conflictData)
|
||||
putSerializable(ARG_LEFT_FILE, file)
|
||||
putParcelable(ARG_RIGHT_FILE, rightFile)
|
||||
putParcelable(ARG_USER, user)
|
||||
}
|
||||
|
||||
return ConflictsResolveDialog().apply {
|
||||
|
@ -314,13 +324,13 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
fun newInstance(
|
||||
context: Context,
|
||||
offlineOperation: OfflineOperationEntity,
|
||||
rightFile: OCFile?,
|
||||
rightFile: OCFile,
|
||||
): ConflictsResolveDialog {
|
||||
val conflictData = getConflictDataForFolderConflict(offlineOperation, rightFile, context)
|
||||
val conflictData = getFolderConflictData(offlineOperation, rightFile, context)
|
||||
|
||||
val bundle = Bundle().apply {
|
||||
putParcelable(CONFLICT_DATA, conflictData)
|
||||
putParcelable(RIGHT_FILE, rightFile)
|
||||
putParcelable(ARG_CONFLICT_DATA, conflictData)
|
||||
putParcelable(ARG_RIGHT_FILE, rightFile)
|
||||
}
|
||||
|
||||
return ConflictsResolveDialog().apply {
|
||||
|
@ -329,9 +339,9 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getConflictDataForFolderConflict(
|
||||
private fun getFolderConflictData(
|
||||
offlineOperation: OfflineOperationEntity,
|
||||
rightFile: OCFile?,
|
||||
rightFile: OCFile,
|
||||
context: Context
|
||||
): ConflictDialogData {
|
||||
val folderName = null
|
||||
|
@ -343,8 +353,8 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
val leftCheckBoxData = ConflictFileData(leftTitle, leftTimestamp.toString(), leftFileSize)
|
||||
|
||||
val rightTitle = context.getString(R.string.prefs_synced_folders_remote_path_title)
|
||||
val rightTimestamp = DisplayUtils.getRelativeTimestamp(context, rightFile?.modificationTimestamp ?: 0)
|
||||
val rightFileSize = DisplayUtils.bytesToHumanReadable(rightFile?.fileLength ?: 0)
|
||||
val rightTimestamp = DisplayUtils.getRelativeTimestamp(context, rightFile.modificationTimestamp)
|
||||
val rightFileSize = DisplayUtils.bytesToHumanReadable(rightFile.fileLength)
|
||||
val rightCheckBoxData = ConflictFileData(rightTitle, rightTimestamp.toString(), rightFileSize)
|
||||
|
||||
val title = context.getString(R.string.conflict_folder_headline)
|
||||
|
@ -353,12 +363,12 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getConflictDataForFileConflict(
|
||||
private fun getFileConflictData(
|
||||
file: File,
|
||||
rightFile: OCFile?,
|
||||
rightFile: OCFile,
|
||||
context: Context
|
||||
): ConflictDialogData {
|
||||
val parentFile = rightFile?.remotePath?.let { File(it).parentFile }
|
||||
val parentFile = File(rightFile.remotePath).parentFile
|
||||
val folderName = if (parentFile != null) {
|
||||
String.format(context.getString(R.string.in_folder), parentFile.absolutePath)
|
||||
} else {
|
||||
|
@ -371,8 +381,8 @@ class ConflictsResolveDialog : DialogFragment(), Injectable {
|
|||
val leftCheckBoxData = ConflictFileData(leftTitle, leftTimestamp.toString(), leftFileSize)
|
||||
|
||||
val rightTitle = context.getString(R.string.conflict_server_file)
|
||||
val rightTimestamp = DisplayUtils.getRelativeTimestamp(context, rightFile?.modificationTimestamp ?: 0)
|
||||
val rightFileSize = DisplayUtils.bytesToHumanReadable(rightFile?.fileLength ?: 0)
|
||||
val rightTimestamp = DisplayUtils.getRelativeTimestamp(context, rightFile.modificationTimestamp)
|
||||
val rightFileSize = DisplayUtils.bytesToHumanReadable(rightFile.fileLength)
|
||||
val rightCheckBoxData = ConflictFileData(rightTitle, rightTimestamp.toString(), rightFileSize)
|
||||
|
||||
val title = context.getString(R.string.choose_which_file)
|
||||
|
|
|
@ -9,6 +9,7 @@ package com.owncloud.android.ui.dialog.parcel
|
|||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.nextcloud.utils.extensions.readParcelableCompat
|
||||
|
||||
data class ConflictDialogData(
|
||||
val folderName: String?,
|
||||
|
@ -66,12 +67,3 @@ data class ConflictFileData(
|
|||
override fun newArray(size: Int): Array<ConflictFileData?> = arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Parcelable> Parcel.readParcelableCompat(classLoader: ClassLoader?): T? {
|
||||
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
|
||||
readParcelable(classLoader, T::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
readParcelable(classLoader)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue