From 9dcdb7d05bd2f72aaf02e3463a4f9508290b9601 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 21 Aug 2024 14:07:44 +0200 Subject: [PATCH] Simplify ConflictResolveDialog Signed-off-by: alperozturk --- .../utils/extensions/ParcableExtensions.kt | 20 +++ .../ui/activity/ConflictsResolveActivity.kt | 50 ++++---- .../ui/dialog/ConflictsResolveDialog.kt | 118 ++++++++++-------- .../ui/dialog/parcel/ConflictDialogData.kt | 10 +- 4 files changed, 109 insertions(+), 89 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/utils/extensions/ParcableExtensions.kt diff --git a/app/src/main/java/com/nextcloud/utils/extensions/ParcableExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/ParcableExtensions.kt new file mode 100644 index 0000000000..a46e999682 --- /dev/null +++ b/app/src/main/java/com/nextcloud/utils/extensions/ParcableExtensions.kt @@ -0,0 +1,20 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2024 Alper Ozturk + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.utils.extensions + +import android.os.Parcel +import android.os.Parcelable + +inline fun 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) + } +} diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.kt index 9e4f780ce1..501a77fcbb 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.kt +++ b/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) + 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 { 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") diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.kt b/app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.kt index d35918036b..1326d51f2a 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.kt +++ b/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 = 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) diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/parcel/ConflictDialogData.kt b/app/src/main/java/com/owncloud/android/ui/dialog/parcel/ConflictDialogData.kt index b0a5e430f7..67fd926bee 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/parcel/ConflictDialogData.kt +++ b/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 = arrayOfNulls(size) } } - -inline fun 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) - } -}