Skip to content

Commit

Permalink
Merge pull request #3976 from TeamAmaze/feature/0971
Browse files Browse the repository at this point in the history
Feature/0971 implement trash bin
  • Loading branch information
VishalNehra authored Nov 26, 2023
2 parents bcbeb77 + 8a786eb commit 7af5f87
Show file tree
Hide file tree
Showing 34 changed files with 989 additions and 41 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ dependencies {
runtimeOnly "com.github.tony19:logback-android:$logbackAndroidVersion"

implementation 'com.google.code.gson:gson:2.9.1'

implementation 'com.github.TeamAmaze:AmazeTrashBin:1.0.10'
}

kotlin {
Expand Down
4 changes: 3 additions & 1 deletion app/proguard.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,6 @@
#Keep constructors that involves an InputStream
-keepclassmembers class * extends org.apache.commons.compress.compressors.CompressorInputStream {
<init>(java.io.InputStream);
}
}

-keep class com.amaze.trashbin.** { *; }
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ class AppsRecyclerAdapter(
} else {
files.add(f1)
}
DeleteTask(fragment.requireContext()).execute(files)
DeleteTask(fragment.requireContext(), false).execute(files)
}
.build()
.show()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class HiddenAdapter(
nomediaFile.mode = OpenMode.FILE
val filesToDelete = ArrayList<HybridFileParcelable>()
filesToDelete.add(nomediaFile)
val task = DeleteTask(context)
val task = DeleteTask(context, false)
task.execute(filesToDelete)
}
DataUtils.getInstance().removeHiddenFile(hiddenFiles[position].path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1458,6 +1458,21 @@ private void showPopup(@NonNull View view, @NonNull final LayoutElementParcelabl
popupMenu.getMenu().findItem(R.id.encrypt).setVisible(true);
}
}
if (rowItem.getMode() == OpenMode.TRASH_BIN) {
popupMenu.getMenu().findItem(R.id.return_select).setVisible(false);
popupMenu.getMenu().findItem(R.id.cut).setVisible(false);
popupMenu.getMenu().findItem(R.id.cpy).setVisible(false);
popupMenu.getMenu().findItem(R.id.rename).setVisible(false);
popupMenu.getMenu().findItem(R.id.encrypt).setVisible(false);
popupMenu.getMenu().findItem(R.id.decrypt).setVisible(false);
popupMenu.getMenu().findItem(R.id.about).setVisible(false);
popupMenu.getMenu().findItem(R.id.compress).setVisible(false);
popupMenu.getMenu().findItem(R.id.share).setVisible(false);
popupMenu.getMenu().findItem(R.id.ex).setVisible(false);
popupMenu.getMenu().findItem(R.id.book).setVisible(false);
popupMenu.getMenu().findItem(R.id.restore).setVisible(true);
popupMenu.getMenu().findItem(R.id.delete).setVisible(true);
}

popupMenu.show();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ public class LayoutElementParcelable implements Parcelable {
public final String desc;
public final String permissions;
public final String symlink;
public final String size;
public final boolean isDirectory;
public final long date, longSize;
public final String dateModification;
public String size;
public boolean isDirectory;
public long date, longSize;
public String dateModification;
public final boolean header;

// same as hfile.modes but different than openmode in Main.java
Expand Down
67 changes: 67 additions & 0 deletions app/src/main/java/com/amaze/filemanager/application/AppConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.amaze.filemanager.application;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.concurrent.Callable;

Expand All @@ -39,25 +40,35 @@
import com.amaze.filemanager.database.ExplorerDatabase;
import com.amaze.filemanager.database.UtilitiesDatabase;
import com.amaze.filemanager.database.UtilsHandler;
import com.amaze.filemanager.fileoperations.exceptions.ShellNotRunningException;
import com.amaze.filemanager.fileoperations.filesystem.OpenMode;
import com.amaze.filemanager.filesystem.HybridFile;
import com.amaze.filemanager.filesystem.ssh.CustomSshJConfig;
import com.amaze.filemanager.ui.fragments.preferencefragments.PreferencesConstants;
import com.amaze.filemanager.ui.provider.UtilitiesProvider;
import com.amaze.filemanager.utils.ScreenUtils;
import com.amaze.trashbin.TrashBin;
import com.amaze.trashbin.TrashBinConfig;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.os.StrictMode;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;

import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import jcifs.Config;
import jcifs.smb.SmbException;

@AcraCore(
buildConfigClass = BuildConfig.class,
Expand All @@ -78,6 +89,11 @@ public class AppConfig extends GlideApplication {

private ExplorerDatabase explorerDatabase;

private TrashBinConfig trashBinConfig;
private TrashBin trashBin;
private static final String TRASH_BIN_BASE_PATH =
Environment.getExternalStorageDirectory().getPath() + File.separator + ".AmazeData";

public UtilitiesProvider getUtilsProvider() {
return utilsProvider;
}
Expand Down Expand Up @@ -253,4 +269,55 @@ protected void initACRA() {
R.string.app_ui_crash));
}
}

public TrashBin getTrashBinInstance() {
if (trashBin == null) {
trashBin =
new TrashBin(
getApplicationContext(),
true,
getTrashBinConfig(),
s -> {
runInBackground(
() -> {
HybridFile file = new HybridFile(OpenMode.TRASH_BIN, s);
try {
file.delete(getMainActivityContext(), false);
} catch (ShellNotRunningException | SmbException e) {
log.warn("failed to delete file in trash bin cleanup", e);
}
});
return true;
},
null);
}
return trashBin;
}

private TrashBinConfig getTrashBinConfig() {
if (trashBinConfig == null) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);

int days =
sharedPrefs.getInt(
PreferencesConstants.KEY_TRASH_BIN_RETENTION_DAYS,
TrashBinConfig.RETENTION_DAYS_INFINITE);
long bytes =
sharedPrefs.getLong(
PreferencesConstants.KEY_TRASH_BIN_RETENTION_BYTES,
TrashBinConfig.RETENTION_BYTES_INFINITE);
int numOfFiles =
sharedPrefs.getInt(
PreferencesConstants.KEY_TRASH_BIN_RETENTION_NUM_OF_FILES,
TrashBinConfig.RETENTION_NUM_OF_FILES);
int intervalHours =
sharedPrefs.getInt(
PreferencesConstants.KEY_TRASH_BIN_CLEANUP_INTERVAL_HOURS,
TrashBinConfig.INTERVAL_CLEANUP_HOURS);
trashBinConfig =
new TrashBinConfig(
TRASH_BIN_BASE_PATH, days, bytes, numOfFiles, intervalHours, false, true);
}
return trashBinConfig;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ public class DeleteTask
private final Context applicationContext;
private final boolean rootMode;
private CompressedExplorerFragment compressedExplorerFragment;

private boolean doDeletePermanently;
private final DataUtils dataUtils = DataUtils.getInstance();

public DeleteTask(@NonNull Context applicationContext) {
public DeleteTask(@NonNull Context applicationContext, @NonNull boolean doDeletePermanently) {
this.applicationContext = applicationContext.getApplicationContext();
this.doDeletePermanently = doDeletePermanently;
rootMode =
PreferenceManager.getDefaultSharedPreferences(applicationContext)
.getBoolean(PreferencesConstants.PREFERENCE_ROOTMODE, false);
Expand All @@ -80,6 +83,7 @@ public DeleteTask(@NonNull Context applicationContext) {
public DeleteTask(
@NonNull Context applicationContext, CompressedExplorerFragment compressedExplorerFragment) {
this.applicationContext = applicationContext.getApplicationContext();
this.doDeletePermanently = false;
rootMode =
PreferenceManager.getDefaultSharedPreferences(applicationContext)
.getBoolean(PreferencesConstants.PREFERENCE_ROOTMODE, false);
Expand Down Expand Up @@ -109,7 +113,7 @@ protected final AsyncTaskResult<Boolean> doInBackground(
}

// delete file from media database
if (!file.isSmb())
if (!file.isSmb() && !file.isSftp())
MediaConnectionUtils.scanFile(
applicationContext, files.toArray(new HybridFile[files.size()]));

Expand Down Expand Up @@ -180,7 +184,15 @@ private boolean doDeleteFile(@NonNull HybridFileParcelable file) throws Exceptio
}
default:
try {
return (file.delete(applicationContext, rootMode));
/* SMB and SFTP (or any remote files that may support in the future) should not be
* supported by recycle bin. - TranceLove
*/
if (!doDeletePermanently
&& !OpenMode.SMB.equals(file.getMode())
&& !OpenMode.SFTP.equals(file.getMode())) {
return file.moveToBin(applicationContext);
}
return file.delete(applicationContext, rootMode);
} catch (ShellNotRunningException | SmbException e) {
LOG.warn("failed to delete files", e);
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
import com.amaze.filemanager.utils.OTGUtil;
import com.amaze.filemanager.utils.OnAsyncTaskFinished;
import com.amaze.filemanager.utils.OnFileFound;
import com.amaze.filemanager.utils.Utils;
import com.amaze.trashbin.TrashBin;
import com.amaze.trashbin.TrashBinFile;
import com.cloudrail.si.interfaces.CloudStorage;

import android.content.ContentResolver;
Expand Down Expand Up @@ -135,7 +138,9 @@ public LoadFilesListTask(
MainFragmentViewModel mainFragmentViewModel = mainFragment.getMainFragmentViewModel();
MainActivityViewModel mainActivityViewModel = mainFragment.getMainActivityViewModel();

if (OpenMode.UNKNOWN.equals(openmode) || OpenMode.CUSTOM.equals(openmode)) {
if (OpenMode.UNKNOWN.equals(openmode)
|| OpenMode.CUSTOM.equals(openmode)
|| OpenMode.TRASH_BIN.equals(openmode)) {
hFile = new HybridFile(openmode, path);
hFile.generateMode(mainFragment.getActivity());
openmode = hFile.getMode();
Expand All @@ -159,6 +164,7 @@ public LoadFilesListTask(
list = listSftp(mainActivityViewModel);
break;
case CUSTOM:
case TRASH_BIN:
list = getCachedMediaList(mainActivityViewModel);
break;
case OTG:
Expand Down Expand Up @@ -191,7 +197,8 @@ public LoadFilesListTask(
}

if (list != null
&& !(openmode == OpenMode.CUSTOM && ((path).equals("5") || (path).equals("6")))) {
&& !(openmode == OpenMode.CUSTOM
&& (("5").equals(path) || ("6").equals(path) || ("7").equals(path)))) {
postListCustomPathProcess(list, mainFragment);
}

Expand All @@ -214,6 +221,7 @@ private List<LayoutElementParcelable> getCachedMediaList(
int mediaType = Integer.parseInt(path);
if (5 == mediaType
|| 6 == mediaType
|| 7 == mediaType
|| mainActivityViewModel.getMediaCacheHash().get(mediaType) == null
|| forceReload) {
switch (Integer.parseInt(path)) {
Expand All @@ -238,10 +246,13 @@ private List<LayoutElementParcelable> getCachedMediaList(
case 6:
list = listRecentFiles();
break;
case 7:
list = listTrashBinFiles();
break;
default:
throw new IllegalStateException();
}
if (5 != mediaType && 6 != mediaType) {
if (5 != mediaType && 6 != mediaType && 7 != mediaType) {
// not saving recent files in cache
mainActivityViewModel.getMediaCacheHash().set(mediaType, list);
}
Expand Down Expand Up @@ -556,6 +567,40 @@ else if (cursor.getCount() > 0 && cursor.moveToFirst()) {
return recentFiles;
}

private @Nullable List<LayoutElementParcelable> listTrashBinFiles() {
final Context context = this.context.get();

if (context == null) {
cancel(true);
return null;
}

TrashBin trashBin = AppConfig.getInstance().getTrashBinInstance();
List<LayoutElementParcelable> deletedFiles = new ArrayList<>();
if (trashBin != null) {
for (TrashBinFile trashBinFile : trashBin.listFilesInBin()) {
HybridFile hybridFile =
new HybridFile(
OpenMode.TRASH_BIN,
trashBinFile.getDeletedPath(
AppConfig.getInstance().getTrashBinInstance().getConfig()),
trashBinFile.getFileName(),
trashBinFile.isDirectory());
if (trashBinFile.getDeleteTime() != null) {
hybridFile.setLastModified(trashBinFile.getDeleteTime() * 1000);
}
LayoutElementParcelable element = hybridFile.generateLayoutElement(context, true);
element.date = trashBinFile.getDeleteTime();
element.longSize = trashBinFile.getSizeBytes();
element.size = Formatter.formatFileSize(context, trashBinFile.getSizeBytes());
element.dateModification = Utils.getDate(context, trashBinFile.getDeleteTime() * 1000);
element.isDirectory = trashBinFile.isDirectory();
deletedFiles.add(element);
}
}
return deletedFiles;
}

private @NonNull List<LayoutElementParcelable> listAppDataDirectories(@NonNull String basePath) {
if (!GenericExtKt.containsPath(FileProperties.ANDROID_DEVICE_DATA_DIRS, basePath)) {
throw new IllegalArgumentException("Invalid base path: [" + basePath + "]");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ public void execute(
for (HybridFileParcelable a : sourceFiles) {
if (!failedFOps.contains(a)) toDelete.add(a);
}
new DeleteTask(c).execute((toDelete));
new DeleteTask(c, true).execute((toDelete));
}
}

Expand Down
Loading

0 comments on commit 7af5f87

Please sign in to comment.