소스 검색

Add FileOperationHelper

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 10 달 전
부모
커밋
153fd9b049

+ 6 - 0
app/src/main/java/com/nextcloud/client/di/AppModule.java

@@ -28,6 +28,7 @@ import com.nextcloud.client.core.ClockImpl;
 import com.nextcloud.client.core.ThreadPoolAsyncRunner;
 import com.nextcloud.client.database.dao.ArbitraryDataDao;
 import com.nextcloud.client.device.DeviceInfo;
+import com.nextcloud.client.jobs.operation.FileOperationHelper;
 import com.nextcloud.client.logger.FileLogHandler;
 import com.nextcloud.client.logger.Logger;
 import com.nextcloud.client.logger.LoggerImpl;
@@ -250,6 +251,11 @@ class AppModule {
         return new PassCodeManager(preferences, clock);
     }
 
+    @Provides
+    FileOperationHelper fileOperationHelper(CurrentAccountProvider currentAccountProvider, Context context) {
+        return new FileOperationHelper(currentAccountProvider.getUser(), context, fileDataStorageManager(currentAccountProvider, context));
+    }
+
     @Provides
     @Singleton
     UsersAndGroupsSearchConfig userAndGroupSearchConfig() {

+ 52 - 0
app/src/main/java/com/nextcloud/client/jobs/operation/FileOperationHelper.kt

@@ -0,0 +1,52 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.nextcloud.client.jobs.operation
+
+import android.content.Context
+import com.nextcloud.client.account.User
+import com.nextcloud.client.network.ClientFactoryImpl
+import com.owncloud.android.datamodel.FileDataStorageManager
+import com.owncloud.android.datamodel.OCFile
+import com.owncloud.android.lib.common.utils.Log_OC
+import com.owncloud.android.operations.RemoveFileOperation
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
+
+class FileOperationHelper(
+    private val user: User,
+    private val context: Context,
+    private val fileDataStorageManager: FileDataStorageManager
+) {
+
+    companion object {
+        private val TAG = FileOperationHelper::class.java.simpleName
+    }
+
+    private val clientFactory = ClientFactoryImpl(context)
+    private val client = clientFactory.create(user)
+
+    @Suppress("TooGenericExceptionCaught", "Deprecation")
+    suspend fun removeFile(file: OCFile, onlyLocalCopy: Boolean, inBackground: Boolean): Boolean = coroutineScope {
+        try {
+            async(Dispatchers.IO) {
+                RemoveFileOperation(
+                    file,
+                    onlyLocalCopy,
+                    user,
+                    inBackground,
+                    context,
+                    fileDataStorageManager
+                )
+            }.await().execute(client).isSuccess
+        } catch (e: Exception) {
+            Log_OC.e(TAG, "Error occurred while removing file: $e")
+            false
+        }
+    }
+}

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

@@ -17,8 +17,10 @@ import android.widget.Toast
 import androidx.fragment.app.FragmentTransaction
 import androidx.lifecycle.lifecycleScope
 import com.nextcloud.client.account.User
+import com.nextcloud.client.database.entity.OfflineOperationEntity
 import com.nextcloud.client.jobs.download.FileDownloadHelper
 import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsNotificationManager
+import com.nextcloud.client.jobs.operation.FileOperationHelper
 import com.nextcloud.client.jobs.upload.FileUploadHelper
 import com.nextcloud.client.jobs.upload.FileUploadWorker
 import com.nextcloud.client.jobs.upload.UploadNotificationManager
@@ -36,6 +38,7 @@ import com.owncloud.android.lib.resources.files.model.RemoteFile
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog.Decision
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog.OnConflictDecisionMadeListener
+import com.owncloud.android.utils.DisplayUtils
 import com.owncloud.android.utils.FileStorageUtils
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -48,6 +51,9 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
     @Inject
     lateinit var uploadsStorageManager: UploadsStorageManager
 
+    @Inject
+    lateinit var fileOperationHelper: FileOperationHelper
+
     private var conflictUploadId: Long = 0
     private var offlineOperationPath: String? = null
     private var existingFile: OCFile? = null
@@ -97,15 +103,19 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
             // version
             val user = user.orElseThrow { RuntimeException() }
 
+            val offlineOperation = if (offlineOperationPath != null) {
+                fileDataStorageManager.offlineOperationDao.getByPath(offlineOperationPath!!)
+            } else {
+                null
+            }
+
             when (decision) {
                 Decision.KEEP_LOCAL -> keepLocal(file, upload, user)
                 Decision.KEEP_BOTH -> keepBoth(file, upload, user)
                 Decision.KEEP_SERVER -> keepServer(file, upload)
-
-                Decision.KEEP_OFFLINE_FOLDER,
-                Decision.KEEP_SERVER_FOLDER,
-                Decision.KEEP_BOTH_FOLDER -> handleFolderConflict(decision)
-
+                Decision.KEEP_OFFLINE_FOLDER -> keepOfflineFolder(newFile, offlineOperation)
+                Decision.KEEP_SERVER_FOLDER -> keepServerFile(offlineOperation)
+                Decision.KEEP_BOTH_FOLDER -> keepBothFolder(offlineOperation)
                 Decision.CANCEL -> Unit
                 else -> Unit
             }
@@ -114,30 +124,37 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
         }
     }
 
-    private fun handleFolderConflict(decision: Decision) {
-        val path = offlineOperationPath ?: return
-        val serverFile = newFile ?: return
-        val offlineOperation = fileDataStorageManager.offlineOperationDao.getByPath(path) ?: return
+    private fun keepBothFolder(offlineOperation: OfflineOperationEntity?) {
+        offlineOperation ?: return
+        fileDataStorageManager.keepOfflineOperationAndServerFile(offlineOperation)
+        backgroundJobManager.startOfflineOperations()
+        offlineOperationNotificationManager.dismissNotification(offlineOperation.id)
+    }
 
-        when(decision) {
-            Decision.KEEP_OFFLINE_FOLDER -> {
-                fileOperationsHelper?.removeFiles(listOf(serverFile), false, false)
-                backgroundJobManager.startOfflineOperations()
-            }
+    private fun keepServerFile(offlineOperation: OfflineOperationEntity?) {
+        val path = offlineOperation?.path ?: return
+        fileDataStorageManager.offlineOperationDao.deleteByPath(path)
 
-            Decision.KEEP_SERVER_FOLDER -> {
-                fileDataStorageManager.offlineOperationDao.deleteByPath(path)
-            }
+        val id = offlineOperation.id ?: return
+        offlineOperationNotificationManager.dismissNotification(id)
+    }
+
+    private fun keepOfflineFolder(serverFile: OCFile?, offlineOperation: OfflineOperationEntity?) {
+        serverFile ?: return
+        offlineOperation ?: return
 
-            Decision.KEEP_BOTH_FOLDER -> {
-                fileDataStorageManager.keepOfflineOperationAndServerFile(offlineOperation)
+        lifecycleScope.launch {
+            val success = fileOperationHelper.removeFile(serverFile, false, false)
+            if (success) {
                 backgroundJobManager.startOfflineOperations()
+                offlineOperationNotificationManager.dismissNotification(offlineOperation.id)
+            } else {
+                DisplayUtils.showSnackMessage(
+                    this@ConflictsResolveActivity,
+                    R.string.conflict_resolver_activity_keep_offline_folder_error_message
+                )
             }
-
-            else -> Unit
         }
-
-        offlineOperationNotificationManager.dismissNotification(offlineOperation.id)
     }
 
     private fun keepLocal(file: OCFile?, upload: OCUpload?, user: User) {

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -1030,6 +1030,7 @@
     <string name="sync_not_enough_space_dialog_title">Not enough space</string>
     <string name="conflict_file_headline">Conflicting file %1$s</string>
     <string name="conflict_folder_headline">Folder Conflict</string>
+    <string name="conflict_resolver_activity_keep_offline_folder_error_message">Error occurred during deleting the remote file</string>
     <string name="conflict_message_description_for_folder">If you select both versions, the local folder will have a number appended to its name.</string>
     <string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string>
     <string name="conflict_local_file">Local file</string>