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.ContextUtil; import com.datarecovery.master.R; import com.datarecovery.master.utils.BoxingUtil; import com.datarecovery.master.utils.FileUtil; import com.datarecovery.master.utils.FilesSearch; import com.datarecovery.master.utils.MediaStoreHelper; import com.datarecovery.master.utils.ToastUtil; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import javax.inject.Inject; import atmob.reactivex.rxjava3.android.schedulers.AndroidSchedulers; 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 int[] tabTitle = {R.string.word, R.string.excel, R.string.ppt, R.string.pdf}; private final List> checkList = new ArrayList<>(); private final MutableLiveData> detectedWordList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData> detectedExcelList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData> detectedPPTList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData> detectedPDFList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData> selectedList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData checkPosition = new MutableLiveData<>(); private final SingleLiveEvent showLoadingEvent = new SingleLiveEvent<>(); private final SingleLiveEvent detectedFinish = new SingleLiveEvent<>(); private final SingleLiveEvent showScanDialogEvent = new SingleLiveEvent<>(); private int totalCount = 0; private final MutableLiveData totalDetectedCount = new MutableLiveData<>(); private final LiveData selectedCountTxt; private Disposable scanDisposable; @Inject public FileRecoverViewModel() { 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()); }); startFileScanning(); for (int i = 0; i < tabTitle.length; i++) checkList.add(new MutableLiveData<>(false)); } 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 getDetectedFinish() { return detectedFinish; } public LiveData getTotalDetectedCount() { return totalDetectedCount; } public LiveData> getSelectedList() { return selectedList; } public LiveData getSelectedCountTxt() { return selectedCountTxt; } public LiveData getShowScanDialogEvent() { return showScanDialogEvent; } public void setCheckPosition(int position) { this.checkPosition.setValue(position); } private void startFileScanning() { FilesSearch.search(ContextUtil.getContext(), FilesSearch.DocumentFile.WORD, FilesSearch.DocumentFile.EXCEL, FilesSearch.DocumentFile.PPT, FilesSearch.DocumentFile.PDF) .take(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); totalCount = 0; totalDetectedCount.setValue(0); } @Override public void onNext(List documentFiles) { if (documentFiles == null || documentFiles.isEmpty()) { return; } totalCount += documentFiles.size(); totalDetectedCount.setValue(totalCount); for (FilesSearch.DocumentFile item : documentFiles) { MutableLiveData> liveData = null; if (item.getCategory() == FilesSearch.DocumentFile.WORD) { liveData = detectedWordList; } else if (item.getCategory() == FilesSearch.DocumentFile.EXCEL) { liveData = detectedExcelList; } else if (item.getCategory() == FilesSearch.DocumentFile.PPT) { liveData = detectedPPTList; } else if (item.getCategory() == FilesSearch.DocumentFile.PDF) { liveData = detectedPDFList; } if (liveData == null) { continue; } List list = getList(liveData); list.add(0, item); liveData.setValue(list); } } @Override public void onError(Throwable t) { showScanDialogEvent.setValue(false); } @Override public void onComplete() { detectedFinish.call(); } }); } public void cancelScan() { if (scanDisposable != null) scanDisposable.dispose(); } private List getList(LiveData> liveData) { List selectList = liveData.getValue(); if (selectList == null) { selectList = new ArrayList<>(); } return selectList; } public void onCheckAllClick(boolean isCheck) { int index = BoxingUtil.boxing(checkPosition.getValue()); getCheckAll(index).setValue(isCheck); int id = tabTitle[index]; MutableLiveData> liveData = null; if (id == R.string.word) { liveData = detectedWordList; } else if (id == R.string.excel) { liveData = detectedExcelList; } else if (id == R.string.ppt) { liveData = detectedPPTList; } else if (id == R.string.pdf) { liveData = detectedPDFList; } if (liveData == null) { return; } List list = getList(liveData); if (list.isEmpty()) { return; } List selectedList = getList(this.selectedList); for (FilesSearch.DocumentFile item : list) { if (item.isCheck() != isCheck) { if (isCheck) { selectedList.add(item); } else { selectedList.remove(item); } } item.setCheck(isCheck); } this.selectedList.setValue(selectedList); } public MutableLiveData getCheckAll(int position) { return checkList.get(position); } public void onExportClick() { List list = selectedList.getValue(); if (list == null || list.size() == 0) { return; } //TODO 判断是否有会员 showLoadingEvent.setValue(true); RxJavaUtil.doInBackground(() -> { for (FilesSearch.DocumentFile item : list) { MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_FILES, item.newInputStream(), FileUtil.getCreateFileName(item.getName(), "")); item.setCheck(false); } return true; }, o -> { getCheckAll(BoxingUtil.boxing(checkPosition.getValue())).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(R.string.export_fail, ToastUtil.LENGTH_SHORT); }); } public void itemClick(FilesSearch.DocumentFile documentFile) { if (documentFile == null) { return; } documentFile.setCheck(!documentFile.isCheck()); List list = getList(selectedList); if (documentFile.isCheck()) { list.add(documentFile); } else { list.remove(documentFile); } this.selectedList.setValue(list); } }