Merge pull request #2717 from kszczek/delete-finished-downloads
Add option to delete files when clearing finished downloads
This commit is contained in:
commit
cef9ccd937
|
@ -5,6 +5,7 @@ import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
@ -35,6 +36,8 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.recyclerview.widget.RecyclerView.Adapter;
|
import androidx.recyclerview.widget.RecyclerView.Adapter;
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||||
|
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
import org.schabi.newpipe.BuildConfig;
|
import org.schabi.newpipe.BuildConfig;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
@ -46,6 +49,7 @@ import java.io.File;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import us.shandian.giga.get.DownloadMission;
|
import us.shandian.giga.get.DownloadMission;
|
||||||
import us.shandian.giga.get.FinishedMission;
|
import us.shandian.giga.get.FinishedMission;
|
||||||
|
@ -104,8 +108,12 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
||||||
private MenuItem mPauseButton;
|
private MenuItem mPauseButton;
|
||||||
private View mEmptyMessage;
|
private View mEmptyMessage;
|
||||||
private RecoverHelper mRecover;
|
private RecoverHelper mRecover;
|
||||||
|
private View mView;
|
||||||
|
private ArrayList<Mission> mHidden;
|
||||||
|
private Snackbar mSnackbar;
|
||||||
|
|
||||||
private final Runnable rUpdater = this::updater;
|
private final Runnable rUpdater = this::updater;
|
||||||
|
private final Runnable rDelete = this::deleteFinishedDownloads;
|
||||||
|
|
||||||
public MissionAdapter(Context context, @NonNull DownloadManager downloadManager, View emptyMessage, View root) {
|
public MissionAdapter(Context context, @NonNull DownloadManager downloadManager, View emptyMessage, View root) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
@ -122,6 +130,10 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
||||||
|
|
||||||
mDeleter = new Deleter(root, mContext, this, mDownloadManager, mIterator, mHandler);
|
mDeleter = new Deleter(root, mContext, this, mDownloadManager, mIterator, mHandler);
|
||||||
|
|
||||||
|
mView = root;
|
||||||
|
|
||||||
|
mHidden = new ArrayList<>();
|
||||||
|
|
||||||
checkEmptyMessageVisibility();
|
checkEmptyMessageVisibility();
|
||||||
onResume();
|
onResume();
|
||||||
}
|
}
|
||||||
|
@ -557,9 +569,50 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearFinishedDownloads() {
|
public void clearFinishedDownloads(boolean delete) {
|
||||||
mDownloadManager.forgetFinishedDownloads();
|
if (delete && mIterator.hasFinishedMissions() && mHidden.isEmpty()) {
|
||||||
applyChanges();
|
for (int i = 0; i < mIterator.getOldListSize(); i++) {
|
||||||
|
FinishedMission mission = mIterator.getItem(i).mission instanceof FinishedMission ? (FinishedMission) mIterator.getItem(i).mission : null;
|
||||||
|
if (mission != null) {
|
||||||
|
mIterator.hide(mission);
|
||||||
|
mHidden.add(mission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
applyChanges();
|
||||||
|
|
||||||
|
String msg = String.format(mContext.getString(R.string.deleted_downloads), mHidden.size());
|
||||||
|
mSnackbar = Snackbar.make(mView, msg, Snackbar.LENGTH_INDEFINITE);
|
||||||
|
mSnackbar.setAction(R.string.undo, s -> {
|
||||||
|
Iterator<Mission> i = mHidden.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
mIterator.unHide(i.next());
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
applyChanges();
|
||||||
|
mHandler.removeCallbacks(rDelete);
|
||||||
|
});
|
||||||
|
mSnackbar.setActionTextColor(Color.YELLOW);
|
||||||
|
mSnackbar.show();
|
||||||
|
|
||||||
|
mHandler.postDelayed(rDelete, 5000);
|
||||||
|
} else if (!delete) {
|
||||||
|
mDownloadManager.forgetFinishedDownloads();
|
||||||
|
applyChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteFinishedDownloads() {
|
||||||
|
if (mSnackbar != null) mSnackbar.dismiss();
|
||||||
|
|
||||||
|
Iterator<Mission> i = mHidden.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
Mission mission = i.next();
|
||||||
|
if (mission != null) {
|
||||||
|
mDownloadManager.deleteMission(mission);
|
||||||
|
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mission.storage.getUri()));
|
||||||
|
}
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handlePopupItem(@NonNull ViewHolderItem h, @NonNull MenuItem option) {
|
private boolean handlePopupItem(@NonNull ViewHolderItem h, @NonNull MenuItem option) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.CheckBox;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -189,10 +190,12 @@ public class MissionsFragment extends Fragment {
|
||||||
return true;
|
return true;
|
||||||
case R.id.clear_list:
|
case R.id.clear_list:
|
||||||
AlertDialog.Builder prompt = new AlertDialog.Builder(mContext);
|
AlertDialog.Builder prompt = new AlertDialog.Builder(mContext);
|
||||||
prompt.setTitle(R.string.clear_finished_download);
|
prompt.setTitle(R.string.clear_download_history);
|
||||||
prompt.setMessage(R.string.confirm_prompt);
|
prompt.setMessage(R.string.confirm_prompt);
|
||||||
prompt.setPositiveButton(android.R.string.ok, (dialog, which) -> mAdapter.clearFinishedDownloads());
|
// Intentionally misusing button's purpose in order to achieve good order
|
||||||
prompt.setNegativeButton(R.string.cancel, null);
|
prompt.setNegativeButton(R.string.clear_download_history, (dialog, which) -> mAdapter.clearFinishedDownloads(false));
|
||||||
|
prompt.setPositiveButton(R.string.delete_downloaded_files, (dialog, which) -> mAdapter.clearFinishedDownloads(true));
|
||||||
|
prompt.setNeutralButton(R.string.cancel, null);
|
||||||
prompt.create().show();
|
prompt.create().show();
|
||||||
return true;
|
return true;
|
||||||
case R.id.start_downloads:
|
case R.id.start_downloads:
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<item android:id="@+id/clear_list"
|
<item android:id="@+id/clear_list"
|
||||||
android:visible="false"
|
android:visible="false"
|
||||||
android:icon="?attr/ic_delete"
|
android:icon="?attr/ic_delete"
|
||||||
android:title="@string/clear_finished_download"
|
android:title="@string/clear_download_history"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
<item android:id="@+id/action_settings"
|
<item android:id="@+id/action_settings"
|
||||||
|
|
|
@ -569,8 +569,10 @@
|
||||||
<string name="error_progress_lost">Progress lost, because the file was deleted</string>
|
<string name="error_progress_lost">Progress lost, because the file was deleted</string>
|
||||||
<string name="error_timeout">Connection timeout</string>
|
<string name="error_timeout">Connection timeout</string>
|
||||||
<string name="error_download_resource_gone">Cannot recover this download</string>
|
<string name="error_download_resource_gone">Cannot recover this download</string>
|
||||||
<string name="clear_finished_download">Clear finished downloads</string>
|
<string name="clear_download_history">Clear download history</string>
|
||||||
<string name="confirm_prompt">Are you sure?</string>
|
<string name="confirm_prompt">Do you want to clear your download history or delete all downloaded files?</string>
|
||||||
|
<string name="delete_downloaded_files">Delete downloaded files</string>
|
||||||
|
<string name="deleted_downloads">Deleted %1$s downloads</string>
|
||||||
<string name="stop">Stop</string>
|
<string name="stop">Stop</string>
|
||||||
<string name="max_retry_msg">Maximum retries</string>
|
<string name="max_retry_msg">Maximum retries</string>
|
||||||
<string name="max_retry_desc">Maximum number of attempts before canceling the download</string>
|
<string name="max_retry_desc">Maximum number of attempts before canceling the download</string>
|
||||||
|
@ -587,5 +589,4 @@
|
||||||
<string name="downloads_storage_use_saf_title">Use SAF</string>
|
<string name="downloads_storage_use_saf_title">Use SAF</string>
|
||||||
<string name="downloads_storage_use_saf_summary">The Storage Access Framework allows downloads to an external SD card.\nNote: some devices are not compatible</string>
|
<string name="downloads_storage_use_saf_summary">The Storage Access Framework allows downloads to an external SD card.\nNote: some devices are not compatible</string>
|
||||||
<string name="choose_instance_prompt">Choose an instance</string>
|
<string name="choose_instance_prompt">Choose an instance</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue