mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 21:55:48 +03:00
Merge pull request #13947 from nextcloud/feature/offline-file-remove
Feature - Offline File Deletion
This commit is contained in:
commit
9d7d5bb283
7 changed files with 108 additions and 30 deletions
|
@ -46,6 +46,11 @@ class OfflineOperationTypeAdapter : JsonSerializer<OfflineOperationType>, JsonDe
|
||||||
jsonObject.addProperty("newName", src.newName)
|
jsonObject.addProperty("newName", src.newName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is OfflineOperationType.RemoveFile -> {
|
||||||
|
jsonObject.addProperty("type", src.type)
|
||||||
|
jsonObject.addProperty("path", src.path)
|
||||||
|
}
|
||||||
|
|
||||||
null -> Unit
|
null -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +83,11 @@ class OfflineOperationTypeAdapter : JsonSerializer<OfflineOperationType>, JsonDe
|
||||||
jsonObject.get("newName").asString
|
jsonObject.get("newName").asString
|
||||||
)
|
)
|
||||||
|
|
||||||
|
OfflineOperationRawType.RemoveFile.name -> OfflineOperationType.RemoveFile(
|
||||||
|
jsonObject.get("type").asString,
|
||||||
|
jsonObject.get("path").asString
|
||||||
|
)
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC
|
import com.owncloud.android.lib.common.utils.Log_OC
|
||||||
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation
|
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation
|
||||||
import com.owncloud.android.operations.CreateFolderOperation
|
import com.owncloud.android.operations.CreateFolderOperation
|
||||||
|
import com.owncloud.android.operations.RemoveFileOperation
|
||||||
import com.owncloud.android.operations.RenameFileOperation
|
import com.owncloud.android.operations.RenameFileOperation
|
||||||
import com.owncloud.android.utils.theme.ViewThemeUtils
|
import com.owncloud.android.utils.theme.ViewThemeUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -163,6 +164,16 @@ class OfflineOperationsWorker(
|
||||||
renameFileOperation?.execute(client) to renameFileOperation
|
renameFileOperation?.execute(client) to renameFileOperation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is OfflineOperationType.RemoveFile -> {
|
||||||
|
val removeFileOperation = withContext(NonCancellable) {
|
||||||
|
val operationType = (operation.type as OfflineOperationType.RemoveFile)
|
||||||
|
val ocFile = fileDataStorageManager.getFileByDecryptedRemotePath(operationType.path)
|
||||||
|
RemoveFileOperation(ocFile, false, user, true, context, fileDataStorageManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFileOperation.execute(client) to removeFileOperation
|
||||||
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Log_OC.d(TAG, "Unsupported operation type: ${operation.type}")
|
Log_OC.d(TAG, "Unsupported operation type: ${operation.type}")
|
||||||
null
|
null
|
||||||
|
@ -186,7 +197,15 @@ class OfflineOperationsWorker(
|
||||||
Log_OC.d(TAG, "$logMessage filename: ${operation.filename}, type: ${operation.type}")
|
Log_OC.d(TAG, "$logMessage filename: ${operation.filename}, type: ${operation.type}")
|
||||||
|
|
||||||
if (result.isSuccess) {
|
if (result.isSuccess) {
|
||||||
repository.updateNextOperations(operation)
|
if (operation.type is OfflineOperationType.RemoveFile) {
|
||||||
|
val operationType = operation.type as OfflineOperationType.RemoveFile
|
||||||
|
fileDataStorageManager.getFileByDecryptedRemotePath(operationType.path)?.let { ocFile ->
|
||||||
|
repository.deleteOperation(ocFile)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
repository.updateNextOperations(operation)
|
||||||
|
}
|
||||||
|
|
||||||
fileDataStorageManager.offlineOperationDao.delete(operation)
|
fileDataStorageManager.offlineOperationDao.delete(operation)
|
||||||
notificationManager.update(totalOperations, currentSuccessfulOperationIndex, operation.filename ?: "")
|
notificationManager.update(totalOperations, currentSuccessfulOperationIndex, operation.filename ?: "")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,10 +24,13 @@ sealed class OfflineOperationType {
|
||||||
var ocFileId: Long,
|
var ocFileId: Long,
|
||||||
val newName: String
|
val newName: String
|
||||||
) : OfflineOperationType()
|
) : OfflineOperationType()
|
||||||
|
|
||||||
|
data class RemoveFile(override val type: String, var path: String) : OfflineOperationType()
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class OfflineOperationRawType {
|
enum class OfflineOperationRawType {
|
||||||
CreateFolder,
|
CreateFolder,
|
||||||
CreateFile,
|
CreateFile,
|
||||||
RenameFile
|
RenameFile,
|
||||||
|
RemoveFile
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,6 +175,10 @@ public class FileDataStorageManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OfflineOperationEntity getOfflineEntityFromOCFile(OCFile file) {
|
||||||
|
return offlineOperationDao.getByPath(file.getDecryptedRemotePath());
|
||||||
|
}
|
||||||
|
|
||||||
public OfflineOperationEntity addCreateFolderOfflineOperation(String path, String filename, Long parentOCFileId) {
|
public OfflineOperationEntity addCreateFolderOfflineOperation(String path, String filename, Long parentOCFileId) {
|
||||||
OfflineOperationEntity entity = new OfflineOperationEntity();
|
OfflineOperationEntity entity = new OfflineOperationEntity();
|
||||||
|
|
||||||
|
@ -246,6 +250,25 @@ public class FileDataStorageManager {
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addRemoveFileOfflineOperation(String path, String filename, Long parentOCFileId) {
|
||||||
|
OfflineOperationEntity entity = new OfflineOperationEntity();
|
||||||
|
|
||||||
|
entity.setFilename(filename);
|
||||||
|
entity.setParentOCFileId(parentOCFileId);
|
||||||
|
|
||||||
|
OfflineOperationType.RemoveFile operationType = new OfflineOperationType.RemoveFile(OfflineOperationRawType.RemoveFile.name(), path);
|
||||||
|
entity.setType(operationType);
|
||||||
|
entity.setPath(path);
|
||||||
|
|
||||||
|
long createdAt = System.currentTimeMillis();
|
||||||
|
long modificationTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
entity.setCreatedAt(createdAt);
|
||||||
|
entity.setModifiedAt(modificationTimestamp / 1000);
|
||||||
|
|
||||||
|
offlineOperationDao.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
public void renameOfflineOperation(OCFile file, String newFolderName) {
|
public void renameOfflineOperation(OCFile file, String newFolderName) {
|
||||||
var entity = offlineOperationDao.getByPath(file.getDecryptedRemotePath());
|
var entity = offlineOperationDao.getByPath(file.getDecryptedRemotePath());
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
|
|
@ -612,28 +612,11 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
localSize = localFile.length();
|
localSize = localFile.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.getFileSize().setVisibility(View.VISIBLE);
|
prepareFileSize(holder, file, localSize);
|
||||||
|
|
||||||
|
|
||||||
if (file.isOfflineOperation()) {
|
|
||||||
holder.getFileSize().setText(MainApp.string(R.string.oc_file_list_adapter_offline_operation_description_text));
|
|
||||||
} else {
|
|
||||||
holder.getFileSize().setText(DisplayUtils.bytesToHumanReadable(localSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.getFileSizeSeparator().setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
final long fileLength = file.getFileLength();
|
final long fileLength = file.getFileLength();
|
||||||
if (fileLength >= 0) {
|
if (fileLength >= 0) {
|
||||||
holder.getFileSize().setVisibility(View.VISIBLE);
|
prepareFileSize(holder, file, fileLength);
|
||||||
|
|
||||||
if (file.isOfflineOperation()) {
|
|
||||||
holder.getFileSize().setText(MainApp.string(R.string.oc_file_list_adapter_offline_operation_description_text));
|
|
||||||
} else {
|
|
||||||
holder.getFileSize().setText(DisplayUtils.bytesToHumanReadable(fileLength));
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.getFileSizeSeparator().setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
holder.getFileSize().setVisibility(View.GONE);
|
holder.getFileSize().setVisibility(View.GONE);
|
||||||
holder.getFileSizeSeparator().setVisibility(View.GONE);
|
holder.getFileSizeSeparator().setVisibility(View.GONE);
|
||||||
|
@ -671,6 +654,28 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
applyVisualsForOfflineOperations(holder, file);
|
applyVisualsForOfflineOperations(holder, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prepareFileSize(ListItemViewHolder holder, OCFile file, long size) {
|
||||||
|
holder.getFileSize().setVisibility(View.VISIBLE);
|
||||||
|
ViewExtensionsKt.setVisibleIf(holder.getFileSizeSeparator(), !file.isOfflineOperation());
|
||||||
|
String fileSizeText = getFileSizeText(file, size);
|
||||||
|
holder.getFileSize().setText(fileSizeText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFileSizeText(OCFile file, long size) {
|
||||||
|
OfflineOperationEntity entity = mStorageManager.getOfflineEntityFromOCFile(file);
|
||||||
|
boolean isRemoveOperation = entity != null && entity.getType() instanceof OfflineOperationType.RemoveFile;
|
||||||
|
|
||||||
|
if (isRemoveOperation) {
|
||||||
|
return activity.getString(R.string.oc_file_list_adapter_offline_operation_remove_description_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.isOfflineOperation()) {
|
||||||
|
return activity.getString(R.string.oc_file_list_adapter_offline_operation_description_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DisplayUtils.bytesToHumanReadable(size);
|
||||||
|
}
|
||||||
|
|
||||||
private void applyVisualsForOfflineOperations(ListItemViewHolder holder, OCFile file) {
|
private void applyVisualsForOfflineOperations(ListItemViewHolder holder, OCFile file) {
|
||||||
ViewExtensionsKt.setVisibleIf(holder.getShared(), !file.isOfflineOperation());
|
ViewExtensionsKt.setVisibleIf(holder.getShared(), !file.isOfflineOperation());
|
||||||
|
|
||||||
|
|
|
@ -90,17 +90,33 @@ class RemoveFilesDialogFragment : ConfirmationDialogFragment(), ConfirmationDial
|
||||||
fileDataStorageManager.deleteOfflineOperation(it)
|
fileDataStorageManager.deleteOfflineOperation(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (files.isNotEmpty()) {
|
if (requireActivity() is FileDisplayActivity) {
|
||||||
val cg = activity as ComponentsGetter?
|
val activity = requireActivity() as FileDisplayActivity
|
||||||
cg?.fileOperationsHelper?.removeFiles(files, onlyLocalCopy, false)
|
activity.connectivityService.isNetworkAndServerAvailable { result ->
|
||||||
}
|
if (result) {
|
||||||
|
if (files.isNotEmpty()) {
|
||||||
|
val cg = activity as ComponentsGetter?
|
||||||
|
cg?.fileOperationsHelper?.removeFiles(files, onlyLocalCopy, false)
|
||||||
|
}
|
||||||
|
|
||||||
if (offlineFiles.isNotEmpty()) {
|
if (offlineFiles.isNotEmpty()) {
|
||||||
val activity = requireActivity() as? FileDisplayActivity
|
activity.refreshCurrentDirectory()
|
||||||
activity?.refreshCurrentDirectory()
|
}
|
||||||
}
|
} else {
|
||||||
|
files.forEach { file ->
|
||||||
|
fileDataStorageManager.addRemoveFileOfflineOperation(
|
||||||
|
file.decryptedRemotePath,
|
||||||
|
file.fileName,
|
||||||
|
file.parentId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
finishActionMode()
|
activity.refreshCurrentDirectory()
|
||||||
|
}
|
||||||
|
|
||||||
|
finishActionMode()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNeutral(callerTag: String?) {
|
override fun onNeutral(callerTag: String?) {
|
||||||
|
|
|
@ -1269,4 +1269,6 @@
|
||||||
<string name="two_way_sync_activity_empty_list_desc">To set up a two way sync folder, please enable it in the details tab of the folder in question.</string>
|
<string name="two_way_sync_activity_empty_list_desc">To set up a two way sync folder, please enable it in the details tab of the folder in question.</string>
|
||||||
<string name="two_way_sync_activity_title">Internal two way sync</string>
|
<string name="two_way_sync_activity_title">Internal two way sync</string>
|
||||||
<string name="two_way_sync_activity_disable_all_button_title">Disable for all folders</string>
|
<string name="two_way_sync_activity_disable_all_button_title">Disable for all folders</string>
|
||||||
|
|
||||||
|
<string name="oc_file_list_adapter_offline_operation_remove_description_text">Pending Remove Operation</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue