|
|
@@ -22,12 +22,14 @@ import com.datarecovery.master.utils.FilesSearch;
|
|
|
import com.datarecovery.master.utils.Maps;
|
|
|
import com.datarecovery.master.utils.MediaStoreHelper;
|
|
|
import com.datarecovery.master.utils.ReportUtil;
|
|
|
+import com.datarecovery.master.utils.ReverseArrayList;
|
|
|
import com.datarecovery.master.utils.ToastUtil;
|
|
|
|
|
|
import org.reactivestreams.Subscriber;
|
|
|
import org.reactivestreams.Subscription;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Iterator;
|
|
|
import java.util.List;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@@ -35,6 +37,8 @@ import javax.inject.Inject;
|
|
|
|
|
|
import atmob.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
|
|
import atmob.reactivex.rxjava3.annotations.NonNull;
|
|
|
+import atmob.reactivex.rxjava3.core.Single;
|
|
|
+import atmob.reactivex.rxjava3.core.SingleObserver;
|
|
|
import atmob.reactivex.rxjava3.disposables.Disposable;
|
|
|
import atmob.rxjava.utils.RxJavaUtil;
|
|
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
|
|
@@ -50,8 +54,11 @@ public class VideoRecoverViewModel extends BaseViewModel {
|
|
|
private final LiveData<String> selectedCountTxt;
|
|
|
private final MutableLiveData<String> detectedLastFileName = new MutableLiveData<>();
|
|
|
private final MutableLiveData<Boolean> checkAll = new MutableLiveData<>(false);
|
|
|
- private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedVideoList = new MutableLiveData<>(new ArrayList<>());
|
|
|
- private final MutableLiveData<List<FilesSearch.DocumentFile>> selectedList = new MutableLiveData<>(new ArrayList<>());
|
|
|
+
|
|
|
+ private final List<FilesSearch.DocumentFile> videoList = new ReverseArrayList<>();
|
|
|
+ private final List<FilesSearch.DocumentFile> selectList = new ArrayList<>();
|
|
|
+ private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedVideoList = new MutableLiveData<>();
|
|
|
+ private final MutableLiveData<List<FilesSearch.DocumentFile>> selectedList = new MutableLiveData<>();
|
|
|
private final MutableLiveData<Boolean> showTrialView = new MutableLiveData<>();
|
|
|
private final SingleLiveEvent<?> showTrialFinishDialog = new SingleLiveEvent<>();
|
|
|
private final SingleLiveEvent<?> showTrialExportFailDialog = new SingleLiveEvent<>();
|
|
|
@@ -148,6 +155,7 @@ public class VideoRecoverViewModel extends BaseViewModel {
|
|
|
scanDisposable = Disposable.fromSubscription(s);
|
|
|
addDisposable(scanDisposable);
|
|
|
showScanDialogEvent.setValue(true);
|
|
|
+ videoList.clear();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -155,12 +163,11 @@ public class VideoRecoverViewModel extends BaseViewModel {
|
|
|
if (documentFiles == null) {
|
|
|
return;
|
|
|
}
|
|
|
- List<FilesSearch.DocumentFile> videoList = getList(detectedVideoList);
|
|
|
for (FilesSearch.DocumentFile documentFile : documentFiles) {
|
|
|
detectedLastFileName.setValue(documentFile.getName());
|
|
|
- videoList.add(0, documentFile);
|
|
|
- detectedVideoList.setValue(videoList);
|
|
|
}
|
|
|
+ videoList.addAll(documentFiles);
|
|
|
+ detectedVideoList.setValue(videoList);
|
|
|
scrollTop.call();
|
|
|
}
|
|
|
|
|
|
@@ -184,35 +191,24 @@ public class VideoRecoverViewModel extends BaseViewModel {
|
|
|
private void setFreeExport() {
|
|
|
if (isTrial) {
|
|
|
showTrialView.setValue(true);
|
|
|
- List<FilesSearch.DocumentFile> list = getList(detectedVideoList);
|
|
|
- if (!list.isEmpty()) {
|
|
|
- list.get(0).setTrial(true);
|
|
|
+ if (!videoList.isEmpty()) {
|
|
|
+ videoList.get(0).setTrial(true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void onCheckAllClick(boolean isCheck) {
|
|
|
checkAll.setValue(isCheck);
|
|
|
- List<FilesSearch.DocumentFile> detectedList = getList(detectedVideoList);
|
|
|
- for (FilesSearch.DocumentFile videoFile : detectedList) {
|
|
|
+ for (FilesSearch.DocumentFile videoFile : videoList) {
|
|
|
videoFile.setCheck(isCheck);
|
|
|
}
|
|
|
- List<FilesSearch.DocumentFile> selectedList = getList(this.selectedList);
|
|
|
if (isCheck) {
|
|
|
- selectedList.clear();
|
|
|
- selectedList.addAll(detectedList);
|
|
|
+ selectList.clear();
|
|
|
+ selectList.addAll(videoList);
|
|
|
} else {
|
|
|
- selectedList.clear();
|
|
|
+ selectList.clear();
|
|
|
}
|
|
|
- this.selectedList.setValue(selectedList);
|
|
|
- }
|
|
|
-
|
|
|
- private List<FilesSearch.DocumentFile> getList(LiveData<List<FilesSearch.DocumentFile>> liveData) {
|
|
|
- List<FilesSearch.DocumentFile> selectList = liveData.getValue();
|
|
|
- if (selectList == null) {
|
|
|
- selectList = new ArrayList<>();
|
|
|
- }
|
|
|
- return selectList;
|
|
|
+ this.selectedList.setValue(selectList);
|
|
|
}
|
|
|
|
|
|
public void cancelScan() {
|
|
|
@@ -222,12 +218,11 @@ public class VideoRecoverViewModel extends BaseViewModel {
|
|
|
}
|
|
|
|
|
|
public void onExportClick() {
|
|
|
- List<FilesSearch.DocumentFile> list = selectedList.getValue();
|
|
|
- if (list == null || list.isEmpty()) {
|
|
|
+ if (selectList.isEmpty()) {
|
|
|
return;
|
|
|
}
|
|
|
if (isTrial) {
|
|
|
- for (FilesSearch.DocumentFile file : list) {
|
|
|
+ for (FilesSearch.DocumentFile file : selectList) {
|
|
|
if (!file.isTrial()) {
|
|
|
showTrialExportFailDialog.call();
|
|
|
return;
|
|
|
@@ -238,35 +233,63 @@ public class VideoRecoverViewModel extends BaseViewModel {
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
- showLoadingEvent.setValue(true);
|
|
|
- RxJavaUtil.doInBackground(() -> {
|
|
|
- for (FilesSearch.DocumentFile item : list) {
|
|
|
- MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_VIDEO, item.newInputStream(), FileUtil.getCreateFileName(MediaStoreHelper.TYPE_VIDEO, item.getName()));
|
|
|
- item.setCheck(false);
|
|
|
- }
|
|
|
- return true;
|
|
|
- }, o -> {
|
|
|
- checkAll.setValue(false);
|
|
|
- showLoadingEvent.setValue(false);
|
|
|
- ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT);
|
|
|
- list.clear();
|
|
|
- selectedList.setValue(list);
|
|
|
- }, throwable -> {
|
|
|
- showLoadingEvent.setValue(false);
|
|
|
- ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
|
|
|
- BuglyHelper.postCatchedException(new Exception("视频导出:", throwable));
|
|
|
- });
|
|
|
+ Single.just(selectList.size())
|
|
|
+ .map(oldSize -> {
|
|
|
+ Iterator<FilesSearch.DocumentFile> iterator = selectList.iterator();
|
|
|
+ int errorCount = 0;
|
|
|
+ Exception exception = null;
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ FilesSearch.DocumentFile item = iterator.next();
|
|
|
+ try {
|
|
|
+ MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_VIDEO, item.newInputStream(), FileUtil.getCreateFileName(MediaStoreHelper.TYPE_VIDEO, item.getName()));
|
|
|
+ item.setCheck(false);
|
|
|
+ iterator.remove();
|
|
|
+ } catch (Exception throwable) {
|
|
|
+ errorCount++;
|
|
|
+ exception = throwable;
|
|
|
+ BuglyHelper.postCatchedException(new Exception("视频导出:", throwable));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (errorCount == oldSize) {
|
|
|
+ throw new Exception("导出失败" + (exception == null ? "" : ":" + exception.getMessage()));
|
|
|
+ } else if (errorCount > 0) {
|
|
|
+ throw new Exception("部分导出失败" + ":" + exception.getMessage());
|
|
|
+ }
|
|
|
+ return errorCount;
|
|
|
+ })
|
|
|
+ .compose(RxJavaUtil.SingleSchedule.io2Main())
|
|
|
+ .subscribe(new SingleObserver<Integer>() {
|
|
|
+ @Override
|
|
|
+ public void onSubscribe(@NonNull Disposable d) {
|
|
|
+ showLoadingEvent.setValue(true);
|
|
|
+ addDisposable(d);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSuccess(@NonNull Integer integer) {
|
|
|
+ showLoadingEvent.setValue(false);
|
|
|
+ selectedList.setValue(selectList);
|
|
|
+ checkAll.setValue(false);
|
|
|
+ ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onError(@NonNull Throwable throwable) {
|
|
|
+ showLoadingEvent.setValue(false);
|
|
|
+ selectedList.setValue(selectList);
|
|
|
+ ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
public void setItemCheck(@NonNull FilesSearch.DocumentFile file) {
|
|
|
file.setCheck(!file.isCheck());
|
|
|
- List<FilesSearch.DocumentFile> list = getList(selectedList);
|
|
|
if (file.isCheck()) {
|
|
|
- list.add(file);
|
|
|
+ selectList.add(file);
|
|
|
} else {
|
|
|
- list.remove(file);
|
|
|
+ selectList.remove(file);
|
|
|
}
|
|
|
- selectedList.setValue(list);
|
|
|
+ selectedList.setValue(selectList);
|
|
|
}
|
|
|
|
|
|
public void closeHintClick() {
|