Browse Source

Simplify ConflictResolveDialog

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 9 months ago
parent
commit
9dcdb7d05b

+ 20 - 0
app/src/main/java/com/nextcloud/utils/extensions/ParcableExtensions.kt

@@ -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)
+    }
+}

+ 23 - 25
app/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.kt

@@ -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)
-
-                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()
-                        }
+        val path = offlineOperationPath ?: return
+        val serverFile = newFile ?: return
+        val offlineOperation = fileDataStorageManager.offlineOperationDao.getByPath(path) ?: return
+
+        when(decision) {
+            Decision.KEEP_OFFLINE_FOLDER -> {
+                fileOperationsHelper?.removeFiles(listOf(serverFile), false, false)
+                backgroundJobManager.startOfflineOperations()
+            }
 
-                        else -> Unit
-                    }
+            Decision.KEEP_SERVER_FOLDER -> {
+                fileDataStorageManager.offlineOperationDao.deleteByPath(path)
+            }
 
-                    offlineOperationNotificationManager.dismissNotification(offlineOperation.id)
-                }
+            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")

+ 63 - 53
app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.kt

@@ -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 = 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
+        val builder = createDialogBuilder()
 
-                    binding.leftCheckbox.isChecked ->
-                        if (data?.folderName == null) Decision.KEEP_OFFLINE_FOLDER else Decision.KEEP_LOCAL
+        setupUI()
+        setOnClickListeners()
 
-                    binding.rightCheckbox.isChecked ->
-                        if (data?.folderName == null) Decision.KEEP_SERVER_FOLDER else Decision.KEEP_SERVER
+        viewThemeUtils.run {
+            platform.themeCheckbox(binding.leftCheckbox)
+            platform.themeCheckbox(binding.rightCheckbox)
+            dialog.colorMaterialAlertDialogBackground(requireContext(), builder)
+        }
 
-                    else -> null
-                }
+        return builder.create()
+    }
 
-                decision?.let { listener?.conflictDecisionMade(it) }
+    private fun createDialogBuilder(): MaterialAlertDialogBuilder {
+        return MaterialAlertDialogBuilder(requireContext())
+            .setView(binding.root)
+            .setPositiveButton(R.string.common_ok) { _: DialogInterface?, _: Int ->
+                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)

+ 1 - 9
app/src/main/java/com/owncloud/android/ui/dialog/parcel/ConflictDialogData.kt

@@ -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)
-    }
-}