package com.yydcdut.note.model.rx;
import android.content.Context;
import com.yydcdut.note.entity.Category;
import com.yydcdut.note.injector.ContextLife;
import com.yydcdut.note.model.dao.CategoryDB;
import com.yydcdut.note.model.rx.exception.RxException;
import java.util.List;
import javax.inject.Inject;
import rx.Observable;
import rx.Subscriber;
import rx.schedulers.Schedulers;
/**
* Created by yuyidong on 15/11/26.
* todo: 有关涉及到的mCache的重构,contact() merge()
*/
public class RxCategory {
private List<Category> mCache;
private CategoryDB mCategoryDB;
@Inject
public RxCategory(@ContextLife("Application") Context context) {
mCategoryDB = new CategoryDB(context);
mCache = mCategoryDB.findAll();
}
/**
* 获得所有的category
*
* @return
*/
public Observable<List<Category>> getAllCategories() {
return Observable.create(new Observable.OnSubscribe<List<Category>>() {
@Override
public void call(Subscriber<? super List<Category>> subscriber) {
subscriber.onNext(mCache);
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
}
/**
* 强制刷新缓存
*
* @return
*/
public Observable<List<Category>> refreshCategories() {
return Observable.create(new Observable.OnSubscribe<List<Category>>() {
@Override
public void call(Subscriber<? super List<Category>> subscriber) {
mCache.clear();
mCache.addAll(mCategoryDB.findAll());
subscriber.onNext(mCache);
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
}
/**
* 设置check哪个category
*
* @param _id
* @return
*/
public Observable<List<Category>> setCategoryMenuPosition(int _id) {
return Observable.from(mCache)
.subscribeOn(Schedulers.io())
.filter(category -> category.isCheck())//过滤出check为true的
.map(category3 -> {
category3.setCheck(false);
mCategoryDB.update(category3);
return mCache;
})
.flatMap(categories -> Observable.from(categories))//转换成一个个Category来处理
.filter(category1 -> category1.getId() == _id)//过滤出与ID相同的Category
.lift(new Observable.Operator<Category, Category>() {
@Override
public Subscriber<? super Category> call(Subscriber<? super Category> subscriber) {
return new Subscriber<Category>() {
/* 因为我想经过filter之后,如果没有数据就返回onError,所以设置这个参数 */
private int mInTimes = 0;
@Override
public void onCompleted() {
if (mInTimes == 0) {
subscriber.onError(new RxException("找不到这个ID的Category"));
}
}
@Override
public void onError(Throwable e) {
subscriber.onError(e);
}
@Override
public void onNext(Category category) {
mInTimes++;
subscriber.onNext(category);
}
};
}
})
.map(category2 -> {
category2.setCheck(true);
int row = mCategoryDB.update(category2);
return row > 0 ? mCache : mCategoryDB.findAll();
});
}
/**
* 添加Category,这个category的check是true
* 要做的事情:
* 1、判断是否有这个字段了
* 2、将其他的Category都取消check
*
* @param label
* @param photosNumber
* @param sort
* @param isCheck
* @return
*/
public Observable<List<Category>> saveCategory(String label, int photosNumber, int sort, boolean isCheck) {
return Observable.create(new Observable.OnSubscribe<Long>() {
private int mInTimes = 0;
@Override
public void call(Subscriber<? super Long> subscriber) {
boolean exist = checkLabelExist(label);
if (exist && mInTimes == 0) {
//在没有mInTimes的时候,这里也会执行,不知道为啥.......
subscriber.onError(new RxException("这个Label已经有了"));
} else {
mInTimes++;
long id = mCategoryDB.save(label, photosNumber, sort, /* isCheck */true);
if (mCache.size() != 0) {
subscriber.onNext(id);
subscriber.onCompleted();
} else {
//如果mCache中没有数据,直接跳到lift中
subscriber.onCompleted();
}
}
}
})
.subscribeOn(Schedulers.io())
.map(aLong -> mCache)//重新获取cache数据
.flatMap(categories1 -> Observable.from(categories1))//转换成一个个的
.filter(category -> category.isCheck())//过滤出check为true的
.lift(new Observable.Operator<List<Category>, Category>() {
@Override
public Subscriber<? super Category> call(Subscriber<? super List<Category>> subscriber) {
return new Subscriber<Category>() {
@Override
public void onCompleted() {
mCache.clear();
mCache.addAll(mCategoryDB.findAll());
subscriber.onNext(mCache);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Category category3) {
//如果有check为true的话,进入到这里,如果没有的话直接进入到onCompleted
category3.setCheck(false);
mCategoryDB.update(category3);
}
};
}
});
}
/**
* 判断这个ShowLabel是否存在
*
* @param newLabel
* @return
*/
private boolean checkLabelExist(String newLabel) {
for (Category item : mCache) {
if (item.getLabel().equals(newLabel)) {
return true;
}
}
return false;
}
/**
* 更新Category
*
* @param category
* @return
*/
public Observable<List<Category>> updateCategory(Category category) {
return Observable.from(mCache)
.subscribeOn(Schedulers.io())
.filter(category1 -> category.getId() == category1.getId())//判断有没有这个category
.map(category2 -> {
mCategoryDB.update(category);
return mCache;
});
}
/**
* 更新Label
*
* @param categoryId
* @param newLabel
* @return
*/
public Observable<List<Category>> updateLabel(int categoryId, String newLabel) {
return Observable.from(mCache)
.subscribeOn(Schedulers.io())
.filter(category1 -> !category1.getLabel().equals(newLabel))//先判断是不是有Category
.filter(category2 -> category2.getId() == categoryId)//过滤出就是这个id的Category
.map(category -> {
category.setLabel(newLabel);
mCategoryDB.update(category);
return mCache;
});
}
/**
* 当做了转移图片到其他Category的时候,做更新操作
*
* @param oldCategoryId
* @param targetCategoryId
* @param changeNumber
* @return
*/
public Observable<List<Category>> updateChangeCategory(int oldCategoryId, int targetCategoryId, int changeNumber) {
return Observable.just(oldCategoryId)//先处理旧的
.subscribeOn(Schedulers.io())
.map(integer -> findCategoryByIdInCache(integer))//找到Category
.map(category -> {//做操作
category.setPhotosNumber(category.getPhotosNumber() - changeNumber);
mCategoryDB.update(category);
return targetCategoryId;
})
.map(integer1 -> findCategoryByIdInCache(integer1))
.map(category1 -> {
category1.setPhotosNumber(category1.getPhotosNumber() + changeNumber);
mCategoryDB.update(category1);
return mCache;
});
}
/**
* 通过ID在cache中找到Category
*
* @param id
* @return
*/
private Category findCategoryByIdInCache(int id) {
for (Category category : mCache) {
if (category.getId() == id) {
return category;
}
}
return null;
}
/**
* 更新顺序
*
* @return
*/
public Observable<List<Category>> updateOrder() {
return Observable.create(new Observable.OnSubscribe<List<Category>>() {
@Override
public void call(Subscriber<? super List<Category>> subscriber) {
for (int i = 0; i < mCache.size(); i++) {
Category category = mCache.get(i);
category.setSort(i);
mCategoryDB.update(category);
}
subscriber.onNext(mCache);
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
}
public Observable<List<Category>> delete(int id) {
return Observable.just(id)
.subscribeOn(Schedulers.io())
.map(integer -> findCategoryByIdInCache(id))
.map(category -> {
mCategoryDB.delete(category);
mCache.clear();
mCache.addAll(mCategoryDB.findAll());
return mCache;
});
}
public Observable<Category> findByCategoryId(int id) {
return Observable.from(mCache)
.subscribeOn(Schedulers.computation())
.filter(category -> category.getId() == id);
}
}