Browse Source

Fixes

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 10 months ago
parent
commit
9879e17a98

+ 3 - 0
app/src/main/AndroidManifest.xml

@@ -266,6 +266,9 @@
             </intent-filter>
             </intent-filter>
         </activity>
         </activity>
 
 
+        <receiver
+            android:name="com.nextcloud.receiver.OfflineOperationActionReceiver"
+            android:exported="false" />
         <receiver
         <receiver
             android:name="com.nextcloud.client.jobs.MediaFoldersDetectionWork$NotificationReceiver"
             android:name="com.nextcloud.client.jobs.MediaFoldersDetectionWork$NotificationReceiver"
             android:exported="false" />
             android:exported="false" />

+ 0 - 3
app/src/main/java/com/nextcloud/client/database/dao/OfflineOperationDao.kt

@@ -16,9 +16,6 @@ import com.nextcloud.client.database.entity.OfflineOperationEntity
 
 
 @Dao
 @Dao
 interface OfflineOperationDao {
 interface OfflineOperationDao {
-    @Query("SELECT (SELECT COUNT(*) FROM offline_operations) == 0")
-    fun isEmpty(): Boolean
-
     @Query("SELECT * FROM offline_operations")
     @Query("SELECT * FROM offline_operations")
     fun getAll(): List<OfflineOperationEntity>
     fun getAll(): List<OfflineOperationEntity>
 
 

+ 24 - 10
app/src/main/java/com/nextcloud/client/jobs/offlineOperations/OfflineOperationsNotificationManager.kt

@@ -9,9 +9,12 @@ package com.nextcloud.client.jobs.offlineOperations
 
 
 import android.app.PendingIntent
 import android.app.PendingIntent
 import android.content.Context
 import android.content.Context
+import android.content.Intent
 import androidx.core.app.NotificationCompat
 import androidx.core.app.NotificationCompat
+import com.nextcloud.client.account.User
 import com.nextcloud.client.database.entity.OfflineOperationEntity
 import com.nextcloud.client.database.entity.OfflineOperationEntity
 import com.nextcloud.client.jobs.notification.WorkerNotificationManager
 import com.nextcloud.client.jobs.notification.WorkerNotificationManager
+import com.nextcloud.receiver.OfflineOperationActionReceiver
 import com.nextcloud.utils.extensions.getErrorMessage
 import com.nextcloud.utils.extensions.getErrorMessage
 import com.owncloud.android.R
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.datamodel.OCFile
@@ -77,7 +80,7 @@ class OfflineOperationsNotificationManager(private val context: Context, viewThe
         }
         }
     }
     }
 
 
-    fun showConflictResolveNotification(file: OCFile, entity: OfflineOperationEntity?) {
+    fun showConflictResolveNotification(file: OCFile, entity: OfflineOperationEntity?, user: User) {
         val path = entity?.path
         val path = entity?.path
         val id = entity?.id
         val id = entity?.id
 
 
@@ -85,19 +88,29 @@ class OfflineOperationsNotificationManager(private val context: Context, viewThe
             return
             return
         }
         }
 
 
-        val intent = ConflictsResolveActivity.createIntent(file, path, context)
-
-        val pendingIntent = PendingIntent.getActivity(
+        val resolveConflictIntent = ConflictsResolveActivity.createIntent(file, path, context)
+        val resolveConflictPendingIntent = PendingIntent.getActivity(
             context,
             context,
             id,
             id,
-            intent,
+            resolveConflictIntent,
             PendingIntent.FLAG_IMMUTABLE
             PendingIntent.FLAG_IMMUTABLE
         )
         )
-
-        val action = NotificationCompat.Action(
+        val resolveConflictAction = NotificationCompat.Action(
             R.drawable.ic_cloud_upload,
             R.drawable.ic_cloud_upload,
             context.getString(R.string.upload_list_resolve_conflict),
             context.getString(R.string.upload_list_resolve_conflict),
-            pendingIntent
+            resolveConflictPendingIntent
+        )
+
+        val deleteIntent = Intent(context, OfflineOperationActionReceiver::class.java).apply {
+            putExtra(OfflineOperationActionReceiver.FILE_PATH, path)
+            putExtra(OfflineOperationActionReceiver.USER, user)
+        }
+        val deletePendingIntent =
+            PendingIntent.getBroadcast(context, 0, deleteIntent, PendingIntent.FLAG_IMMUTABLE)
+        val deleteAction = NotificationCompat.Action(
+            R.drawable.ic_delete,
+            context.getString(R.string.offline_operations_worker_notification_delete_offline_folder),
+            deletePendingIntent
         )
         )
 
 
         val title = context.getString(
         val title = context.getString(
@@ -108,8 +121,9 @@ class OfflineOperationsNotificationManager(private val context: Context, viewThe
         notificationBuilder
         notificationBuilder
             .clearActions()
             .clearActions()
             .setContentTitle(title)
             .setContentTitle(title)
-            .setContentIntent(pendingIntent)
-            .addAction(action)
+            .setContentIntent(resolveConflictPendingIntent)
+            .addAction(deleteAction)
+            .addAction(resolveConflictAction)
 
 
         notificationManager.notify(id, notificationBuilder.build())
         notificationManager.notify(id, notificationBuilder.build())
     }
     }

+ 2 - 3
app/src/main/java/com/nextcloud/client/jobs/offlineOperations/OfflineOperationsWorker.kt

@@ -60,14 +60,13 @@ class OfflineOperationsWorker(
             return@coroutineScope Result.success()
             return@coroutineScope Result.success()
         }
         }
 
 
-        val isEmpty = fileDataStorageManager.offlineOperationDao.isEmpty()
-        if (isEmpty) {
+        val operations = fileDataStorageManager.offlineOperationDao.getAll()
+        if (operations.isEmpty()) {
             Log_OC.d(TAG, "OfflineOperationsWorker cancelled, no offline operations were found")
             Log_OC.d(TAG, "OfflineOperationsWorker cancelled, no offline operations were found")
             return@coroutineScope Result.success()
             return@coroutineScope Result.success()
         }
         }
 
 
         val client = clientFactory.create(user)
         val client = clientFactory.create(user)
-        val operations = fileDataStorageManager.offlineOperationDao.getAll()
 
 
         notificationManager.start()
         notificationManager.start()
 
 

+ 30 - 0
app/src/main/java/com/nextcloud/receiver/OfflineOperationActionReceiver.kt

@@ -0,0 +1,30 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.nextcloud.receiver
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import com.nextcloud.client.account.User
+import com.nextcloud.utils.extensions.getParcelableArgument
+import com.owncloud.android.datamodel.FileDataStorageManager
+
+class OfflineOperationActionReceiver : BroadcastReceiver() {
+    companion object {
+        const val FILE_PATH = "FILE_PATH"
+        const val USER = "USER"
+    }
+
+    override fun onReceive(context: Context?, intent: Intent?) {
+        val path = intent?.getStringExtra(FILE_PATH) ?: return
+        val user = intent.getParcelableArgument(USER, User::class.java) ?: return
+        val fileDataStorageManager = FileDataStorageManager(user, context?.contentResolver)
+        fileDataStorageManager.offlineOperationDao.deleteByPath(path)
+        // TODO Update notification
+    }
+}

+ 14 - 9
app/src/main/java/com/nextcloud/utils/extensions/RemoteOperationResultExtensions.kt

@@ -10,6 +10,7 @@ package com.nextcloud.utils.extensions
 import com.nextcloud.client.database.entity.OfflineOperationEntity
 import com.nextcloud.client.database.entity.OfflineOperationEntity
 import com.owncloud.android.MainApp
 import com.owncloud.android.MainApp
 import com.owncloud.android.R
 import com.owncloud.android.R
+import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.lib.common.operations.RemoteOperation
 import com.owncloud.android.lib.common.operations.RemoteOperation
 import com.owncloud.android.lib.common.operations.RemoteOperationResult
 import com.owncloud.android.lib.common.operations.RemoteOperationResult
@@ -24,19 +25,23 @@ fun Pair<RemoteOperationResult<*>?, RemoteOperation<*>?>?.getErrorMessage(): Str
 }
 }
 
 
 fun RemoteOperationResult<*>?.getConflictedRemoteIdsWithOfflineOperations(
 fun RemoteOperationResult<*>?.getConflictedRemoteIdsWithOfflineOperations(
-    offlineOperations: List<OfflineOperationEntity>
-): HashMap<String, String?>? {
+    offlineOperations: List<OfflineOperationEntity>,
+    fileDataStorageManager: FileDataStorageManager
+): HashMap<String, String>? {
     val newFiles = toOCFile() ?: return null
     val newFiles = toOCFile() ?: return null
+    val result = hashMapOf<String, String>()
 
 
-    val conflictedMap = newFiles
-        .flatMap { file ->
-            offlineOperations
-                .filter { it.filename == file.fileName }
-                .map { file.remoteId to it.path }
+    offlineOperations.forEach { operation ->
+        newFiles.forEach { file ->
+            if (fileDataStorageManager.fileExists(operation.path) && operation.filename == file.fileName) {
+                operation.path?.let { path ->
+                    result[file.remoteId] = path
+                }
+            }
         }
         }
-        .toMap(HashMap())
+    }
 
 
-    return conflictedMap.ifEmpty { null }
+    return result.ifEmpty { null }
 }
 }
 
 
 @Suppress("Deprecation")
 @Suppress("Deprecation")

+ 29 - 31
app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java

@@ -92,7 +92,7 @@ public class RefreshFolderOperation extends RemoteOperation {
     /**
     /**
      * Access to the local database
      * Access to the local database
      */
      */
-    private final FileDataStorageManager mStorageManager;
+    private final FileDataStorageManager fileDataStorageManager;
 
 
     /**
     /**
      * Account where the file to synchronize belongs
      * Account where the file to synchronize belongs
@@ -171,7 +171,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         mLocalFolder = folder;
         mLocalFolder = folder;
         mCurrentSyncTime = currentSyncTime;
         mCurrentSyncTime = currentSyncTime;
         mSyncFullAccount = syncFullAccount;
         mSyncFullAccount = syncFullAccount;
-        mStorageManager = dataStorageManager;
+        fileDataStorageManager = dataStorageManager;
         this.user = user;
         this.user = user;
         mContext = context;
         mContext = context;
         mForgottenLocalFiles = new HashMap<>();
         mForgottenLocalFiles = new HashMap<>();
@@ -192,7 +192,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         mLocalFolder = folder;
         mLocalFolder = folder;
         mCurrentSyncTime = currentSyncTime;
         mCurrentSyncTime = currentSyncTime;
         mSyncFullAccount = syncFullAccount;
         mSyncFullAccount = syncFullAccount;
-        mStorageManager = dataStorageManager;
+        fileDataStorageManager = dataStorageManager;
         this.user = user;
         this.user = user;
         mContext = context;
         mContext = context;
         mForgottenLocalFiles = new HashMap<>();
         mForgottenLocalFiles = new HashMap<>();
@@ -248,7 +248,7 @@ public class RefreshFolderOperation extends RemoteOperation {
                 // TODO catch IllegalStateException, show properly to user
                 // TODO catch IllegalStateException, show properly to user
                 result = fetchAndSyncRemoteFolder(client);
                 result = fetchAndSyncRemoteFolder(client);
             } else {
             } else {
-                mChildren = mStorageManager.getFolderContent(mLocalFolder, false);
+                mChildren = fileDataStorageManager.getFolderContent(mLocalFolder, false);
             }
             }
 
 
             if (result.isSuccess()) {
             if (result.isSuccess()) {
@@ -259,15 +259,13 @@ public class RefreshFolderOperation extends RemoteOperation {
             }
             }
 
 
             mLocalFolder.setLastSyncDateForData(System.currentTimeMillis());
             mLocalFolder.setLastSyncDateForData(System.currentTimeMillis());
-            mStorageManager.saveFile(mLocalFolder);
+            fileDataStorageManager.saveFile(mLocalFolder);
         }
         }
 
 
         checkFolderConflictData(result);
         checkFolderConflictData(result);
 
 
         if (!mSyncFullAccount && mRemoteFolderChanged) {
         if (!mSyncFullAccount && mRemoteFolderChanged) {
-            sendLocalBroadcast(
-                EVENT_SINGLE_FOLDER_CONTENTS_SYNCED, mLocalFolder.getRemotePath(), result
-                              );
+            sendLocalBroadcast(EVENT_SINGLE_FOLDER_CONTENTS_SYNCED, mLocalFolder.getRemotePath(), result);
         }
         }
 
 
         if (result.isSuccess() && !mSyncFullAccount && !mOnlyFileMetadata) {
         if (result.isSuccess() && !mSyncFullAccount && !mOnlyFileMetadata) {
@@ -275,9 +273,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         }
         }
 
 
         if (!mSyncFullAccount) {
         if (!mSyncFullAccount) {
-            sendLocalBroadcast(
-                EVENT_SINGLE_FOLDER_SHARES_SYNCED, mLocalFolder.getRemotePath(), result
-                              );
+            sendLocalBroadcast(EVENT_SINGLE_FOLDER_SHARES_SYNCED, mLocalFolder.getRemotePath(), result);
         }
         }
 
 
         return result;
         return result;
@@ -286,9 +282,11 @@ public class RefreshFolderOperation extends RemoteOperation {
     private static HashMap<String, String> lastConflictData = new HashMap<>();
     private static HashMap<String, String> lastConflictData = new HashMap<>();
 
 
     private void checkFolderConflictData(RemoteOperationResult result) {
     private void checkFolderConflictData(RemoteOperationResult result) {
-        var offlineOperations = mStorageManager.offlineOperationDao.getAll();
-        var conflictData = RemoteOperationResultExtensionsKt.getConflictedRemoteIdsWithOfflineOperations(result, offlineOperations);
-        if (conflictData != null && !conflictData.isEmpty() && !conflictData.equals(lastConflictData)) {
+        var offlineOperations = fileDataStorageManager.offlineOperationDao.getAll();
+        if (offlineOperations.isEmpty()) return;
+
+        var conflictData = RemoteOperationResultExtensionsKt.getConflictedRemoteIdsWithOfflineOperations(result, offlineOperations, fileDataStorageManager);
+        if (conflictData != null && !conflictData.equals(lastConflictData)) {
             lastConflictData = new HashMap<>(conflictData);
             lastConflictData = new HashMap<>(conflictData);
             sendFolderSyncConflictEventBroadcast(conflictData);
             sendFolderSyncConflictEventBroadcast(conflictData);
         }
         }
@@ -313,7 +311,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         try {
         try {
             NextcloudClient nextcloudClient = OwnCloudClientFactory.createNextcloudClient(user, mContext);
             NextcloudClient nextcloudClient = OwnCloudClientFactory.createNextcloudClient(user, mContext);
 
 
-            RemoteOperationResult<UserInfo> result = new GetUserProfileOperation(mStorageManager).execute(nextcloudClient);
+            RemoteOperationResult<UserInfo> result = new GetUserProfileOperation(fileDataStorageManager).execute(nextcloudClient);
             if (!result.isSuccess()) {
             if (!result.isSuccess()) {
                 Log_OC.w(TAG, "Couldn't update user profile from server");
                 Log_OC.w(TAG, "Couldn't update user profile from server");
             } else {
             } else {
@@ -329,9 +327,9 @@ public class RefreshFolderOperation extends RemoteOperation {
         String oldDirectEditingEtag = arbitraryDataProvider.getValue(user,
         String oldDirectEditingEtag = arbitraryDataProvider.getValue(user,
                                                                      ArbitraryDataProvider.DIRECT_EDITING_ETAG);
                                                                      ArbitraryDataProvider.DIRECT_EDITING_ETAG);
 
 
-        RemoteOperationResult result = new GetCapabilitiesOperation(mStorageManager).execute(mContext);
+        RemoteOperationResult result = new GetCapabilitiesOperation(fileDataStorageManager).execute(mContext);
         if (result.isSuccess()) {
         if (result.isSuccess()) {
-            String newDirectEditingEtag = mStorageManager.getCapability(user.getAccountName()).getDirectEditingEtag();
+            String newDirectEditingEtag = fileDataStorageManager.getCapability(user.getAccountName()).getDirectEditingEtag();
 
 
             if (!oldDirectEditingEtag.equalsIgnoreCase(newDirectEditingEtag)) {
             if (!oldDirectEditingEtag.equalsIgnoreCase(newDirectEditingEtag)) {
                 updateDirectEditing(arbitraryDataProvider, newDirectEditingEtag);
                 updateDirectEditing(arbitraryDataProvider, newDirectEditingEtag);
@@ -450,13 +448,13 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
     }
 
 
     private void removeLocalFolder() {
     private void removeLocalFolder() {
-        if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
+        if (fileDataStorageManager.fileExists(mLocalFolder.getFileId())) {
             String currentSavePath = FileStorageUtils.getSavePath(user.getAccountName());
             String currentSavePath = FileStorageUtils.getSavePath(user.getAccountName());
-            mStorageManager.removeFolder(
+            fileDataStorageManager.removeFolder(
                 mLocalFolder,
                 mLocalFolder,
                 true,
                 true,
                 mLocalFolder.isDown() && mLocalFolder.getStoragePath().startsWith(currentSavePath)
                 mLocalFolder.isDown() && mLocalFolder.getStoragePath().startsWith(currentSavePath)
-                                        );
+                                               );
         }
         }
     }
     }
 
 
@@ -471,7 +469,7 @@ public class RefreshFolderOperation extends RemoteOperation {
      */
      */
     private void synchronizeData(List<Object> folderAndFiles) {
     private void synchronizeData(List<Object> folderAndFiles) {
         // get 'fresh data' from the database
         // get 'fresh data' from the database
-        mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
+        mLocalFolder = fileDataStorageManager.getFileByPath(mLocalFolder.getRemotePath());
 
 
         if (mLocalFolder == null) {
         if (mLocalFolder == null) {
             Log_OC.d(TAG,"mLocalFolder cannot be null");
             Log_OC.d(TAG,"mLocalFolder cannot be null");
@@ -489,7 +487,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         mFilesToSyncContents.clear();
         mFilesToSyncContents.clear();
 
 
         // if local folder is encrypted, download fresh metadata
         // if local folder is encrypted, download fresh metadata
-        boolean encryptedAncestor = FileStorageUtils.checkEncryptionStatus(mLocalFolder, mStorageManager);
+        boolean encryptedAncestor = FileStorageUtils.checkEncryptionStatus(mLocalFolder, fileDataStorageManager);
         mLocalFolder.setEncrypted(encryptedAncestor);
         mLocalFolder.setEncrypted(encryptedAncestor);
 
 
         // update permission
         // update permission
@@ -525,11 +523,11 @@ public class RefreshFolderOperation extends RemoteOperation {
         if (object instanceof DecryptedFolderMetadataFileV1) {
         if (object instanceof DecryptedFolderMetadataFileV1) {
             e2EVersion = E2EVersion.V1_2;
             e2EVersion = E2EVersion.V1_2;
             localFilesMap = prefillLocalFilesMap((DecryptedFolderMetadataFileV1) object,
             localFilesMap = prefillLocalFilesMap((DecryptedFolderMetadataFileV1) object,
-                                                 mStorageManager.getFolderContent(mLocalFolder, false));
+                                                 fileDataStorageManager.getFolderContent(mLocalFolder, false));
         } else {
         } else {
             e2EVersion = E2EVersion.V2_0;
             e2EVersion = E2EVersion.V2_0;
             localFilesMap = prefillLocalFilesMap((DecryptedFolderMetadataFile) object,
             localFilesMap = prefillLocalFilesMap((DecryptedFolderMetadataFile) object,
-                                                 mStorageManager.getFolderContent(mLocalFolder, false));
+                                                 fileDataStorageManager.getFolderContent(mLocalFolder, false));
 
 
             // update counter
             // update counter
             if (object != null) {
             if (object != null) {
@@ -557,7 +555,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
 
             // TODO better implementation is needed
             // TODO better implementation is needed
             if (localFile == null) {
             if (localFile == null) {
-                localFile = mStorageManager.getFileByPath(updatedFile.getRemotePath());
+                localFile = fileDataStorageManager.getFileByPath(updatedFile.getRemotePath());
             }
             }
 
 
             // add to updatedFile data about LOCAL STATE (not existing in server)
             // add to updatedFile data about LOCAL STATE (not existing in server)
@@ -576,11 +574,11 @@ public class RefreshFolderOperation extends RemoteOperation {
 
 
             // update file name for encrypted files
             // update file name for encrypted files
             if (e2EVersion == E2EVersion.V1_2) {
             if (e2EVersion == E2EVersion.V1_2) {
-                updateFileNameForEncryptedFileV1(mStorageManager,
+                updateFileNameForEncryptedFileV1(fileDataStorageManager,
                                                  (DecryptedFolderMetadataFileV1) object,
                                                  (DecryptedFolderMetadataFileV1) object,
                                                  updatedFile);
                                                  updatedFile);
             } else {
             } else {
-                updateFileNameForEncryptedFile(mStorageManager,
+                updateFileNameForEncryptedFile(fileDataStorageManager,
                                                (DecryptedFolderMetadataFile) object,
                                                (DecryptedFolderMetadataFile) object,
                                                updatedFile);
                                                updatedFile);
                 if (localFile != null) {
                 if (localFile != null) {
@@ -599,15 +597,15 @@ public class RefreshFolderOperation extends RemoteOperation {
         // save updated contents in local database
         // save updated contents in local database
         // update file name for encrypted files
         // update file name for encrypted files
         if (e2EVersion == E2EVersion.V1_2) {
         if (e2EVersion == E2EVersion.V1_2) {
-            updateFileNameForEncryptedFileV1(mStorageManager,
+            updateFileNameForEncryptedFileV1(fileDataStorageManager,
                                              (DecryptedFolderMetadataFileV1) object,
                                              (DecryptedFolderMetadataFileV1) object,
                                              mLocalFolder);
                                              mLocalFolder);
         } else {
         } else {
-            updateFileNameForEncryptedFile(mStorageManager,
+            updateFileNameForEncryptedFile(fileDataStorageManager,
                                            (DecryptedFolderMetadataFile) object,
                                            (DecryptedFolderMetadataFile) object,
                                            mLocalFolder);
                                            mLocalFolder);
         }
         }
-        mStorageManager.saveFolder(remoteFolder, updatedFiles, localFilesMap.values());
+        fileDataStorageManager.saveFolder(remoteFolder, updatedFiles, localFilesMap.values());
 
 
         mChildren = updatedFiles;
         mChildren = updatedFiles;
     }
     }
@@ -837,7 +835,7 @@ public class RefreshFolderOperation extends RemoteOperation {
                     shares.add(share);
                     shares.add(share);
                 }
                 }
             }
             }
-            mStorageManager.saveSharesInFolder(shares, mLocalFolder);
+            fileDataStorageManager.saveSharesInFolder(shares, mLocalFolder);
         }
         }
 
 
         return result;
         return result;

+ 0 - 1
app/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.kt

@@ -40,7 +40,6 @@ import com.owncloud.android.ui.dialog.ConflictsResolveDialog.Decision
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog.OnConflictDecisionMadeListener
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog.OnConflictDecisionMadeListener
 import com.owncloud.android.utils.FileStorageUtils
 import com.owncloud.android.utils.FileStorageUtils
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import javax.inject.Inject
 import javax.inject.Inject
 
 

+ 3 - 1
app/src/main/java/com/owncloud/android/ui/activity/fileDisplayActivity/OfflineFolderConflictManager.kt

@@ -46,7 +46,9 @@ class OfflineFolderConflictManager(private val activity: FileDisplayActivity) {
             val file = activity.storageManager.getFileByRemoteId(remoteId)
             val file = activity.storageManager.getFileByRemoteId(remoteId)
             file?.let {
             file?.let {
                 val entity = activity.storageManager.offlineOperationDao.getByPath(path)
                 val entity = activity.storageManager.offlineOperationDao.getByPath(path)
-                notificationManager.showConflictResolveNotification(file, entity)
+                if (activity.user.isPresent) {
+                    notificationManager.showConflictResolveNotification(file, entity, activity.user.get())
+                }
             }
             }
         }
         }
     }
     }

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

@@ -30,6 +30,7 @@
     <string name="app_config_base_url_title">Base Url</string>
     <string name="app_config_base_url_title">Base Url</string>
     <string name="app_config_proxy_host_title">Proxy Host Name</string>
     <string name="app_config_proxy_host_title">Proxy Host Name</string>
     <string name="app_config_proxy_port_title">Proxy Port</string>
     <string name="app_config_proxy_port_title">Proxy Port</string>
+    <string name="offline_operations_worker_notification_delete_offline_folder">Delete Offline Folder</string>
     <string name="offline_operations_worker_notification_conflict_text">Conflicted Folder: %s</string>
     <string name="offline_operations_worker_notification_conflict_text">Conflicted Folder: %s</string>
     <string name="offline_operations_worker_notification_start_text">Starting Offline Operations</string>
     <string name="offline_operations_worker_notification_start_text">Starting Offline Operations</string>
     <string name="offline_operations_worker_notification_error_text">The offline operation cannot be completed. %s</string>
     <string name="offline_operations_worker_notification_error_text">The offline operation cannot be completed. %s</string>