package com.yydcdut.note.presenters.home.impl;
import android.app.Fragment;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;
import com.yydcdut.note.R;
import com.yydcdut.note.aspect.permission.AspectPermission;
import com.yydcdut.note.bus.CategoryCreateEvent;
import com.yydcdut.note.bus.CategoryMoveEvent;
import com.yydcdut.note.bus.PhotoNoteCreateEvent;
import com.yydcdut.note.bus.PhotoNoteDeleteEvent;
import com.yydcdut.note.entity.Category;
import com.yydcdut.note.entity.PhotoNote;
import com.yydcdut.note.injector.ContextLife;
import com.yydcdut.note.model.compare.ComparatorFactory;
import com.yydcdut.note.model.rx.RxCategory;
import com.yydcdut.note.model.rx.RxPhotoNote;
import com.yydcdut.note.model.rx.RxSandBox;
import com.yydcdut.note.presenters.home.IAlbumPresenter;
import com.yydcdut.note.utils.FilePathUtils;
import com.yydcdut.note.utils.ImageManager.ImageLoaderManager;
import com.yydcdut.note.utils.LocalStorageUtils;
import com.yydcdut.note.utils.PermissionUtils;
import com.yydcdut.note.utils.Utils;
import com.yydcdut.note.utils.YLog;
import com.yydcdut.note.utils.permission.Permission;
import com.yydcdut.note.views.IView;
import com.yydcdut.note.views.home.IAlbumView;
import org.greenrobot.eventbus.EventBus;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.inject.Inject;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
/**
* Created by yuyidong on 15/11/20.
*/
public class AlbumPresenterImpl implements IAlbumPresenter {
private IAlbumView mAlbumView;
private int mCategoryId = -1;
private int mAlbumSortKind;
private Context mContext;
private Fragment mFragment;
private LocalStorageUtils mLocalStorageUtils;
private RxCategory mRxCategory;
private RxPhotoNote mRxPhotoNote;
private RxSandBox mRxSandBox;
@Inject
public AlbumPresenterImpl(@ContextLife("Activity") Context context, Fragment fragment,
RxCategory rxCategory, RxPhotoNote rxPhotoNote, RxSandBox rxSandBox,
LocalStorageUtils localStorageUtils) {
mContext = context;
mFragment = fragment;
mRxCategory = rxCategory;
mRxPhotoNote = rxPhotoNote;
mRxSandBox = rxSandBox;
mLocalStorageUtils = localStorageUtils;
mAlbumSortKind = mLocalStorageUtils.getSortKind();
}
@Override
public Context getContext() {
return mContext;
}
@Override
public void attachView(IView iView) {
mAlbumView = (IAlbumView) iView;
mRxPhotoNote.findByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> mAlbumView.setAdapter(photoNoteList),
(throwable -> YLog.e(throwable)));
changeTitle();
}
private void changeTitle() {
mRxCategory.getAllCategories()
.flatMap(categories -> Observable.from(categories))
.filter(category -> category.getId() == mCategoryId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(category1 -> mAlbumView.setToolBarTitle(category1.getLabel()),
(throwable -> YLog.e(throwable)));
}
@Override
public void detachView() {
}
@Override
public void bindData(int categoryId) {
mCategoryId = categoryId;
}
@Override
public void checkSandBox() {
/**
* 主要针对于拍完照回到这个界面之后判断沙盒里面还要数据没
*/
new Handler().postDelayed(() -> {
//todo RxJava有delay的方法,写这的时候还不知道怎么用,等重构完回来改
mRxSandBox.getNumber()
.subscribe(integer -> {
if (integer > 0) {
mAlbumView.startSandBoxService();
}
}, (throwable -> YLog.e(throwable)));
}, 3000);
}
@Override
public void setAlbumSort(int sort) {
mAlbumSortKind = sort;
mLocalStorageUtils.setSortKind(mAlbumSortKind);
}
@Override
public void saveAlbumSort() {
mLocalStorageUtils.setSortKind(mAlbumSortKind);
}
@Override
public int getAlbumSort() {
return mAlbumSortKind;
}
@Override
public void jump2DetailActivity(int position) {
mAlbumView.jump2DetailActivity(mCategoryId, position, mAlbumSortKind);
}
@Override
public void updateFromBroadcast(boolean broadcast_process, boolean broadcast_service, boolean broadcast_photo) {
//当图片数据改变的时候,比如滤镜,Service作图
//另外个进程发来广播的时候
//todo 这里可以弄动画,需要计算的过程
//// TODO: 16/2/19 改为本地广播
if (broadcast_process || broadcast_service) {
mRxPhotoNote.refreshByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> mAlbumView.updateData(photoNoteList),
(throwable -> YLog.e(throwable)));
} else if (broadcast_photo) {
mAlbumView.notifyDataSetChanged();
}
}
@Override
public void sortData() {
mRxPhotoNote.findByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> mAlbumView.notifyDataSetChanged(),
(throwable -> YLog.e(throwable)));
}
@Override
public void changeCategoryWithPhotos(int categoryId) {
mCategoryId = categoryId;
mRxPhotoNote.findByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> mAlbumView.updateData(photoNoteList),
(throwable -> YLog.e(throwable)));
changeTitle();
}
@Override
public void movePhotos2AnotherCategory() {
mRxCategory.getAllCategories()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(categories -> {
final String[] categoryIdStringArray = new String[categories.size()];
final String[] categoryLabelArray = new String[categories.size()];
for (int i = 0; i < categoryIdStringArray.length; i++) {
categoryIdStringArray[i] = categories.get(i).getId() + "";
categoryLabelArray[i] = categories.get(i).getLabel();
}
mAlbumView.showMovePhotos2AnotherCategoryDialog(categoryIdStringArray, categoryLabelArray);
}, (throwable -> YLog.e(throwable)));
}
@Override
public void changePhotosCategory(int toCategoryId) {
if (mCategoryId != toCategoryId) {
mRxPhotoNote.findByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.map(photoNoteList -> {
TreeMap<Integer, PhotoNote> map = getTreeMap();
for (int i = 0; i < photoNoteList.size(); i++) {
PhotoNote photoNote = photoNoteList.get(i);
if (photoNote.isSelected()) {
photoNote.setSelected(false);
photoNote.setCategoryId(toCategoryId);
map.put(i, photoNote);
}
}
int times = 0;
for (Map.Entry<Integer, PhotoNote> entry : map.entrySet()) {
photoNoteList.remove(entry.getValue());
mAlbumView.notifyItemRemoved(entry.getKey() - times);//todo 这个在这里合适吗?觉得严重的不合适
mRxPhotoNote.updatePhotoNote(entry.getValue()).subscribe((photoNotes -> {
}), (throwable -> YLog.e(throwable)));
times++;
}
return map.size();
})
.subscribe(integer -> {
mRxCategory.updateChangeCategory(mCategoryId, toCategoryId, integer)
.subscribe(categories -> {
mRxPhotoNote.refreshByCategoryId(mCategoryId, ComparatorFactory.FACTORY_NOT_SORT).subscribe(
(photoNoteList) -> mAlbumView.updateDataNoChange(photoNoteList),
(throwable -> YLog.e(throwable)));
mRxPhotoNote.refreshByCategoryId(toCategoryId, ComparatorFactory.FACTORY_NOT_SORT).subscribe(
photoNotes -> {
}, (throwable -> YLog.e(throwable))
);
EventBus.getDefault().post(new CategoryMoveEvent());
}, (throwable -> YLog.e(throwable)));
}, (throwable -> YLog.e(throwable)));
}
}
@Override
public void deletePhotos() {
//注意java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
mRxPhotoNote.findByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> {
TreeMap<Integer, PhotoNote> map = getTreeMap();
for (int i = 0; i < photoNoteList.size(); i++) {
PhotoNote photoNote = photoNoteList.get(i);
if (photoNote.isSelected()) {
map.put(i, photoNote);
}
}
int times = 0;
for (Map.Entry<Integer, PhotoNote> entry : map.entrySet()) {
photoNoteList.remove(entry.getValue());
mAlbumView.notifyItemRemoved(entry.getKey() - times);
times++;
mRxPhotoNote.deletePhotoNote(entry.getValue())
.subscribe(photoNotes -> {
FilePathUtils.deleteAllFiles(entry.getValue().getPhotoName());
mAlbumView.updateDataNoChange(photoNoteList);
}, (throwable -> YLog.e(throwable)));
}
EventBus.getDefault().post(new PhotoNoteDeleteEvent());
}, (throwable -> YLog.e(throwable)));
}
/**
* 得到经过Key(Integer)的排序的map
*
* @return
*/
private TreeMap<Integer, PhotoNote> getTreeMap() {
return new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
return lhs - rhs;
}
});
}
@Override
public void createCategory(String newCategoryLabel) {
mRxCategory.getAllCategories()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(categories -> {
int totalNumber = categories.size();
if (!TextUtils.isEmpty(newCategoryLabel)) {
mRxCategory.saveCategory(newCategoryLabel, 0, totalNumber, true)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(categories1 -> {
boolean success = false;
for (Category category : categories1) {
if (category.getLabel().equals(newCategoryLabel)) {
mAlbumView.changeActivityListMenuCategoryChecked(category);
EventBus.getDefault().post(new CategoryCreateEvent());
success = true;
break;
}
}
if (!success) {
mAlbumView.showToast(mContext.getResources().getString(R.string.toast_fail));
}
}, (throwable -> YLog.e(throwable)));
} else {
mAlbumView.showToast(mContext.getResources().getString(R.string.toast_fail));
}
}, (throwable -> YLog.e(throwable)));
}
@Override
public void savePhotoFromLocal(final Uri imageUri) {
PhotoNote photoNote = new PhotoNote(System.currentTimeMillis() + ".jpg", System.currentTimeMillis(),
System.currentTimeMillis(), "", "", System.currentTimeMillis(),
System.currentTimeMillis(), mCategoryId);
mRxPhotoNote.savePhotoNote(photoNote)
.map(photoNote1 -> {
//复制大图
ContentResolver cr = mContext.getContentResolver();
try {
FilePathUtils.copyFile(cr.openInputStream(imageUri), photoNote1.getBigPhotoPathWithoutFile());
//保存小图
FilePathUtils.saveSmallPhotoFromBigPhoto(photoNote1.getBigPhotoPathWithFile(), photoNote1.getPhotoName());
} catch (FileNotFoundException e) {
YLog.e(e);
} catch (IOException e) {
YLog.e(e);
}
photoNote1.setPaletteColor(Utils.getPaletteColor(ImageLoaderManager.loadImageSync(photoNote.getBigPhotoPathWithFile())));
mRxPhotoNote.updatePhotoNote(photoNote1).subscribe(photoNotes -> {
}, (throwable -> YLog.e(throwable)));
return photoNote1;
})
.doOnSubscribe(() -> mAlbumView.showProgressBar())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(photoNote2 -> {
EventBus.getDefault().post(new PhotoNoteCreateEvent());
//因为是最新时间,即“图片创建事件”、“图片修改时间”、“笔记创建时间”、“笔记修改时间”,所以要么在最前面,要么在最后面//// TODO: 15/11/20 还是因时间来判断插入到哪里,所以要计算
mRxPhotoNote.findByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> {
mAlbumView.updateData(photoNoteList);
switch (mAlbumSortKind) {
case ComparatorFactory.FACTORY_CREATE_CLOSE:
case ComparatorFactory.FACTORY_EDITED_CLOSE:
mAlbumView.notifyItemInserted(photoNoteList.size() - 1);
break;
case ComparatorFactory.FACTORY_CREATE_FAR:
case ComparatorFactory.FACTORY_EDITED_FAR:
mAlbumView.notifyItemInserted(0);
break;
}
mAlbumView.hideProgressBar();
});
}, (throwable -> YLog.e(throwable)));
}
@Override
public void savePhotoFromSystemCamera() {
PhotoNote photoNote = new PhotoNote(System.currentTimeMillis() + ".jpg", System.currentTimeMillis(),
System.currentTimeMillis(), "", "", System.currentTimeMillis(),
System.currentTimeMillis(), mCategoryId);
mRxPhotoNote.savePhotoNote(photoNote)
.map(photoNote1 -> {
try {
//复制大图
FilePathUtils.copyFile(FilePathUtils.getTempFilePath(), photoNote1.getBigPhotoPathWithoutFile());
//保存小图
FilePathUtils.saveSmallPhotoFromBigPhoto(photoNote.getBigPhotoPathWithFile(), photoNote.getPhotoName());
} catch (FileNotFoundException e) {
YLog.e(e);
} catch (IOException e) {
YLog.e(e);
}
photoNote1.setPaletteColor(Utils.getPaletteColor(ImageLoaderManager.loadImageSync(photoNote.getBigPhotoPathWithFile())));
mRxPhotoNote.updatePhotoNote(photoNote1).subscribe(photoNotes -> {
}, (throwable -> YLog.e(throwable)));
return photoNote1;
})
.doOnSubscribe(() -> mAlbumView.showProgressBar())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(photoNote2 -> {
EventBus.getDefault().post(new PhotoNoteCreateEvent());
//因为是最新时间,即“图片创建事件”、“图片修改时间”、“笔记创建时间”、“笔记修改时间”,所以要么在最前面,要么在最后面//// TODO: 15/11/20 还是因时间来判断插入到哪里,所以要计算
mRxPhotoNote.findByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> {
mAlbumView.updateData(photoNoteList);
switch (mAlbumSortKind) {
case ComparatorFactory.FACTORY_CREATE_CLOSE:
case ComparatorFactory.FACTORY_EDITED_CLOSE:
mAlbumView.notifyItemInserted(photoNoteList.size() - 1);
break;
case ComparatorFactory.FACTORY_CREATE_FAR:
case ComparatorFactory.FACTORY_EDITED_FAR:
mAlbumView.notifyItemInserted(0);
break;
}
mAlbumView.hideProgressBar();
});
}, (throwable -> YLog.e(throwable)));
}
@Override
public void savePhotosFromGallery(ArrayList<String> pathList) {
List<PhotoNote> photoNotes = new ArrayList<>(pathList.size());
for (String path : pathList) {
PhotoNote photoNote = new PhotoNote(System.currentTimeMillis() + ".jpg", System.currentTimeMillis(),
System.currentTimeMillis(), "", "", System.currentTimeMillis(),
System.currentTimeMillis(), mCategoryId);
photoNote.setTag(path);
photoNotes.add(photoNote);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
YLog.e(e);
}
}
mRxPhotoNote.savePhotoNotes(photoNotes)
.flatMap(photoNotes1 -> Observable.from(photoNotes))//注意看这里是photoNotes
.map(photoNote -> {
String path = (String) photoNote.getTag();
if (!TextUtils.isEmpty(path)) {
try {
//复制大图
FilePathUtils.copyFile(path, photoNote.getBigPhotoPathWithoutFile());
//保存小图
FilePathUtils.saveSmallPhotoFromBigPhoto(photoNote.getBigPhotoPathWithFile(), photoNote.getPhotoName());
photoNote.setPaletteColor(Utils.getPaletteColor(ImageLoaderManager.loadImageSync(photoNote.getBigPhotoPathWithFile())));
} catch (IOException e) {
YLog.e(e);
}
}
return photoNote;
})
.lift(new Observable.Operator<Integer, PhotoNote>() {
@Override
public Subscriber<? super PhotoNote> call(Subscriber<? super Integer> subscriber) {
return new Subscriber<PhotoNote>() {
@Override
public void onCompleted() {
subscriber.onNext(mCategoryId);
subscriber.onCompleted();
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(PhotoNote photoNote) {
}
};
}
})
.doOnSubscribe(() -> mAlbumView.showProgressBar())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(integer -> {
EventBus.getDefault().post(new PhotoNoteCreateEvent());
mRxPhotoNote.refreshByCategoryId(mCategoryId, mAlbumSortKind)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoNoteList -> {
mAlbumView.updateData(photoNoteList);
mAlbumView.notifyDataSetChanged();
mAlbumView.hideProgressBar();
}, (throwable -> YLog.e(throwable)));
}, (throwable -> YLog.e(throwable)));
}
@Override
public void jump2Camera() {
if (mLocalStorageUtils.getCameraSystem()) {
mAlbumView.jump2CameraSystemActivity();
} else {
getPermissionAndJumpCameraActivity();
}
}
@Override
public boolean checkStorageEnough() {
if (!FilePathUtils.isSDCardStoredEnough()) {
mAlbumView.showToast(mContext.getResources().getString(R.string.no_space));
return false;
}
return true;
}
@Override
public int calculateGridNumber() {
return mLocalStorageUtils.getAlbumItemNumber();
}
@Permission(PermissionUtils.CODE_CAMERA)
@AspectPermission(PermissionUtils.CODE_CAMERA)
private void getPermissionAndJumpCameraActivity() {
mAlbumView.jump2CameraActivity(mCategoryId);
}
}