package com.datarecovery.master.module.filerecover; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.Transformations; import com.atmob.app.lib.base.BaseViewModel; import com.atmob.app.lib.livedata.SingleLiveEvent; import com.atmob.common.runtime.ActivityUtil; import com.atmob.common.runtime.ContextUtil; import com.datarecovery.master.R; import com.datarecovery.master.data.consts.EventId; import com.datarecovery.master.data.repositories.DeviceFuncRepository; import com.datarecovery.master.handler.EventHelper; import com.datarecovery.master.module.member.MemberActivity; import com.datarecovery.master.module.member.MemberType; import com.datarecovery.master.sdk.bugly.BuglyHelper; import com.datarecovery.master.utils.BoxingUtil; import com.datarecovery.master.utils.FileUtil; import com.datarecovery.master.utils.FilesSearch; import com.datarecovery.master.utils.ImageDeepDetector; 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; 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; @HiltViewModel public class FileRecoverViewModel extends BaseViewModel { private final long SCANNING_COUNTDOWN = 1000 * 60 * 6; private final long SCANNING_IS_TRIAL_COUNTDOWN = 1000 * 5; private final int[] tabTitle = {R.string.word, R.string.excel, R.string.ppt, R.string.pdf}; private final List> checkList = new ArrayList<>(); private final List wordList = new ReverseArrayList<>(); private final List excelList = new ReverseArrayList<>(); private final List pptList = new ReverseArrayList<>(); private final List pdfList = new ReverseArrayList<>(); private final List selectList = new ArrayList<>(); private final MutableLiveData> detectedWordList = new MutableLiveData<>(); private final MutableLiveData> detectedExcelList = new MutableLiveData<>(); private final MutableLiveData> detectedPPTList = new MutableLiveData<>(); private final MutableLiveData> detectedPDFList = new MutableLiveData<>(); private final MutableLiveData> selectedList = new MutableLiveData<>(); private final SingleLiveEvent scrollTop = new SingleLiveEvent<>(); private final MutableLiveData showTrialView = new MutableLiveData<>(); private final MutableLiveData detectedLastFileName = new MutableLiveData<>(); private final MutableLiveData checkPosition = new MutableLiveData<>(); private final SingleLiveEvent showTrialFinishDialog = new SingleLiveEvent<>(); private final SingleLiveEvent showTrialExportFailDialog = new SingleLiveEvent<>(); private final SingleLiveEvent showLoadingEvent = new SingleLiveEvent<>(); private final SingleLiveEvent showScanDialogEvent = new SingleLiveEvent<>(); private final DeviceFuncRepository deviceFuncRepository; private final LiveData selectedCountTxt; private Disposable scanDisposable; private boolean isTrial; @Inject public FileRecoverViewModel(DeviceFuncRepository deviceFuncRepository) { this.deviceFuncRepository = deviceFuncRepository; selectedCountTxt = Transformations.map(selectedList, list -> { if (list == null || list.isEmpty()) { return ContextUtil.getContext().getString(R.string.export); } return ContextUtil.getContext().getString(R.string.export_count, list.size()); }); for (int i = 0; i < tabTitle.length; i++) checkList.add(new MutableLiveData<>(false)); EventHelper.report(EventId.hf1000508); EventHelper.timeEvent(EventId.hf1000523); } public LiveData getScrollTop() { return scrollTop; } public LiveData getShowTrialFinishDialog() { return showTrialFinishDialog; } public LiveData getShowTrialExportFailDialog() { return showTrialExportFailDialog; } public LiveData getShowTrialView() { return showTrialView; } public LiveData getDetectedLastFileName() { return detectedLastFileName; } public boolean isTrial() { return isTrial; } public LiveData getCheckPosition() { return checkPosition; } public int[] getTabTitle() { return tabTitle; } public LiveData> getDetectedWordList() { return detectedWordList; } public LiveData> getDetectedExcelList() { return detectedExcelList; } public LiveData> getDetectedPPTList() { return detectedPPTList; } public LiveData> getDetectedPDFList() { return detectedPDFList; } public LiveData getShowLoadingEvent() { return showLoadingEvent; } public LiveData> getSelectedList() { return selectedList; } public LiveData getSelectedCountTxt() { return selectedCountTxt; } public LiveData getShowScanDialogEvent() { return showScanDialogEvent; } public void setCheckPosition(int position) { this.checkPosition.setValue(position); } public void startFileScanning() { if (scanDisposable != null && !scanDisposable.isDisposed()) { return; } FilesSearch.search(ContextUtil.getContext(), FilesSearch.DocumentFile.WORD, FilesSearch.DocumentFile.EXCEL, FilesSearch.DocumentFile.PPT, FilesSearch.DocumentFile.PDF) .take(isTrial ? SCANNING_IS_TRIAL_COUNTDOWN : SCANNING_COUNTDOWN, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber>() { @Override public void onSubscribe(Subscription s) { s.request(Integer.MAX_VALUE); scanDisposable = Disposable.fromSubscription(s); addDisposable(scanDisposable); showScanDialogEvent.setValue(true); wordList.clear(); excelList.clear(); pptList.clear(); pdfList.clear(); selectList.clear(); } @Override public void onNext(List documentFiles) { if (documentFiles == null || documentFiles.isEmpty()) { return; } int wordCount = 0; int excelCount = 0; int pptCount = 0; int pdfCount = 0; for (FilesSearch.DocumentFile item : documentFiles) { detectedLastFileName.setValue(item.getName()); if (item.getCategory() == FilesSearch.DocumentFile.WORD) { wordCount++; wordList.add(item); } else if (item.getCategory() == FilesSearch.DocumentFile.EXCEL) { excelCount++; excelList.add(item); } else if (item.getCategory() == FilesSearch.DocumentFile.PPT) { pptCount++; pptList.add(item); } else if (item.getCategory() == FilesSearch.DocumentFile.PDF) { pdfCount++; pdfList.add(item); } } if (wordCount > 0) { detectedWordList.setValue(wordList); } if (excelCount > 0) { detectedExcelList.setValue(excelList); } if (pptCount > 0) { detectedPPTList.setValue(pptList); } if (pdfCount > 0) { detectedPDFList.setValue(pdfList); } scrollTop.call(); } @Override public void onError(Throwable t) { showScanDialogEvent.setValue(false); } @Override public void onComplete() { setFreeExport(); if (isTrial) showTrialFinishDialog.call(); showScanDialogEvent.setValue(false); } }); } public void cancelScan() { if (scanDisposable != null) scanDisposable.dispose(); showScanDialogEvent.setValue(false); setFreeExport(); } private void setFreeExport() { if (isTrial) { showTrialView.setValue(true); if (!wordList.isEmpty()) { wordList.get(0).setTrial(true); } if (!excelList.isEmpty()) { excelList.get(0).setTrial(true); } if (!pptList.isEmpty()) { pptList.get(0).setTrial(true); } if (!pdfList.isEmpty()) { pdfList.get(0).setTrial(true); } } } public void onCheckAllClick(boolean isCheck) { int index = BoxingUtil.boxing(checkPosition.getValue()); getCheckAll(index).setValue(isCheck); int id = tabTitle[index]; List list = null; if (id == R.string.word) { list = wordList; } else if (id == R.string.excel) { list = excelList; } else if (id == R.string.ppt) { list = pptList; } else if (id == R.string.pdf) { list = pdfList; } if (list == null || list.isEmpty()) { return; } for (FilesSearch.DocumentFile item : list) { if (item.isCheck() != isCheck) { if (isCheck) { selectList.add(item); } else { selectList.remove(item); } } item.setCheck(isCheck); } this.selectedList.setValue(selectList); } public MutableLiveData getCheckAll(int position) { return checkList.get(position); } public void onExportClick() { if (selectList == null || selectList.isEmpty()) { return; } if (isTrial) { for (FilesSearch.DocumentFile file : selectList) { if (!file.isTrial()) { showTrialExportFailDialog.call(); return; } } } else { if (!deviceFuncRepository.isHaveAuth(MemberType.APP_FILE_RECOVER)) { return; } } Single.just(selectList.size()) .map(oldSize -> { Iterator iterator = selectList.iterator(); int errorCount = 0; Exception exception = null; while (iterator.hasNext()) { FilesSearch.DocumentFile item = iterator.next(); try { MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_FILES, item.newInputStream(), FileUtil.getCreateFileName(MediaStoreHelper.TYPE_FILES, 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() { @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); ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT); getCheckAll(BoxingUtil.boxing(checkPosition.getValue())).setValue(false); } @Override public void onError(@NonNull Throwable throwable) { showLoadingEvent.setValue(false); selectedList.setValue(selectList); ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT); } }); } public void itemClick(FilesSearch.DocumentFile documentFile) { if (documentFile == null) { return; } documentFile.setCheck(!documentFile.isCheck()); if (documentFile.isCheck()) { selectList.add(documentFile); } else { selectList.remove(documentFile); } this.selectedList.setValue(selectList); } @Override protected void onCleared() { super.onCleared(); EventHelper.report(EventId.hf1000523); } public void setIsTrial(boolean isTrial) { this.isTrial = isTrial; } public void onTrialRecoverClick() { MemberActivity.start(ActivityUtil.getTopActivity(), MemberType.APP_FILE_RECOVER); } public void onViewTrialRecoverClick() { EventHelper.report(EventId.hf1001117, Maps.asMap(EventId.EVENT_ID, ReportUtil.getReportId(MemberType.APP_FILE_RECOVER))); MemberActivity.start(ActivityUtil.getTopActivity(), MemberType.APP_FILE_RECOVER); } public void scrollPosition(int lastCompletelyItemPosition, int itemCount) { if (scanDisposable == null || !scanDisposable.isDisposed()) { return; } if (lastCompletelyItemPosition == itemCount - 1 && !BoxingUtil.boxing(showScanDialogEvent.getValue())) { showTrialFinishDialog.call(); EventHelper.report(EventId.hf1001119, Maps.asMap(EventId.EVENT_ID, ReportUtil.getReportId(MemberType.APP_FILE_RECOVER))); } } public void showTrialFinishDialog() { showTrialFinishDialog.call(); } }