package com.leon.androidplus.data; import android.util.SparseArray; import com.avos.avoscloud.AVException; import com.avos.avoscloud.AVObject; import com.avos.avoscloud.AVQuery; import com.avos.avoscloud.FindCallback; import com.leon.androidplus.app.Constant; import com.leon.androidplus.data.model.Article; import com.leon.androidplus.data.model.User; import com.leon.androidplus.data.model.UserArticleFavourMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; @Singleton public class ArticleDataRepository implements ArticleDataSource { private SparseArray<List<Article>> mArticleByTagCache = new SparseArray<>(); private List<Article> mArticlesCache; private List<Article> mUserFavouredArticlesCache; private List<UserArticleFavourMap> mUserArticleFavourMaps; @Inject public ArticleDataRepository() { } @Override public void saveArticle(Article article, final SaveCallback callback) { article.saveInBackground(new com.avos.avoscloud.SaveCallback() { @Override public void done(AVException e) { if (e == null) { callback.onSaveSuccess(); } else { callback.onSaveFailed(e.getLocalizedMessage()); } } }); } @Override public void getArticlesByTag(int tagId, LoadCallback<Article> callback) { getArticlesFromServer(tagId, callback, false); } private void getArticlesFromServer(final int tagId, final LoadCallback<Article> callback, final boolean isLoadMore) { //获取文章查询对象 final AVQuery<Article> articleAVQuery = AVQuery.getQuery(Article.class); //配置查询条件 articleAVQuery.include(Article.USER) .selectKeys(Arrays.asList(Article.TITLE, Article.DESC, Article.FAVOUR_COUNT, Article.TAG, Article.URL, Article.USER_NAME, Article.USER_AVATAR)) .limit(Constant.DEFAULT_PAGE_SIZE); //如果是热门标签,则按文章点赞数排序,以创建时间为第二排序条件,并且点赞次数大于0 if (tagId == Article.TAG_HOT) { articleAVQuery.orderByDescending(Article.FAVOUR_COUNT) .addDescendingOrder(Article.CREATED_AT) .whereGreaterThan(Article.FAVOUR_COUNT, 0); } else {//其他标签,以文章创建时间排序 articleAVQuery.whereEqualTo(Article.TAG, tagId) .orderByDescending(Article.CREATED_AT); } //加载更多数据的处理 if (isLoadMore) { articleAVQuery.whereLessThan(Article.CREATED_AT, getLastTagArticleCreatedAt(tagId)); } //开始查询 articleAVQuery.findInBackground(new FindCallback<Article>() { @Override public void done(List<Article> list, AVException e) { if (e == null) { if (isLoadMore) { mArticleByTagCache.get(tagId).addAll(list); } else { mArticleByTagCache.put(tagId, list); } callback.onLoadSuccess(list); } else { callback.onLoadFailed(e.getLocalizedMessage()); } } }); } @Override public void getMoreArticlesByTag(final int tagId, final LoadCallback<Article> callback) { getArticlesFromServer(tagId, callback, true); } private Date getLastTagArticleCreatedAt(int tagId) { List<Article> articles = mArticleByTagCache.get(tagId); return articles.get(articles.size() - 1).getCreatedAt(); } @Override public void getUserSharedArticles(String userId, final LoadCallback<Article> callback) { getUserSharedArticlesFromServer(userId, callback, false); } private void getUserSharedArticlesFromServer(String userId, final LoadCallback<Article> callback, final boolean isLoadMore) { AVQuery<Article> articleAVQuery = AVQuery.getQuery(Article.class); try { User user = AVObject.createWithoutData(User.class, userId); articleAVQuery.whereEqualTo(Article.USER, user) .orderByDescending(Article.CREATED_AT) .limit(Constant.DEFAULT_PAGE_SIZE); if (isLoadMore) { articleAVQuery.whereLessThan(Article.CREATED_AT, getLastArticleCreatedAt()); } articleAVQuery.findInBackground(new FindCallback<Article>() { @Override public void done(List<Article> list, AVException e) { if (e == null) { if (isLoadMore) { mArticlesCache.addAll(list); } else { mArticlesCache = list; } callback.onLoadSuccess(list); } else { callback.onLoadFailed(e.getLocalizedMessage()); } } }); } catch (AVException e) { e.printStackTrace(); } } @Override public void getMoreUserSharedArticles(String userId, final LoadCallback<Article> callback) { getUserSharedArticlesFromServer(userId, callback, true); } @Override public void refreshUserShareArticles(String userId, LoadCallback<Article> callback) { if (mArticlesCache != null) { mArticlesCache.clear(); } getUserSharedArticles(userId, callback); } public Date getLastArticleCreatedAt() { return mArticlesCache.get(mArticlesCache.size() - 1).getCreatedAt(); } @Override public void getUserFavouredArticles(String userId, final LoadCallback<Article> callback) { getUserFavouredArticlesFromServer(userId, callback, false); } private void getUserFavouredArticlesFromServer(String userId, final LoadCallback<Article> callback, final boolean isLoadMore) { AVQuery<UserArticleFavourMap> query = AVQuery.getQuery(UserArticleFavourMap.class); try { AVObject avObject = AVObject.createWithoutData(User.class, userId); query.whereEqualTo(UserArticleFavourMap.USER, avObject) .include(UserArticleFavourMap.ARTICLE) .limit(Constant.DEFAULT_PAGE_SIZE) .orderByDescending(UserArticleFavourMap.CREATED_AT); if (isLoadMore) { query.whereLessThan(UserArticleFavourMap.CREATED_AT, getLastUserArticleFavourMapCreatedAt()); } query.findInBackground(new FindCallback<UserArticleFavourMap>() { @Override public void done(List<UserArticleFavourMap> list, AVException e) { if (e == null) { if (isLoadMore) { mUserArticleFavourMaps.addAll(list); } else { mUserArticleFavourMaps = list; mUserFavouredArticlesCache = new ArrayList<>(); } for (int i = 0; i < list.size(); i++) { try { Article article = list.get(i).getAVObject("article", Article.class); mUserFavouredArticlesCache.add(article); } catch (Exception e1) { e1.printStackTrace(); callback.onLoadFailed(e1.getLocalizedMessage()); } } callback.onLoadSuccess(mUserFavouredArticlesCache); } else { callback.onLoadFailed(e.getLocalizedMessage()); } } }); } catch (AVException e) { e.printStackTrace(); callback.onLoadFailed(e.getLocalizedMessage()); } } @Override public void refreshUserFavouredArticles(String userId, LoadCallback<Article> callback) { if (mUserFavouredArticlesCache != null) { mUserFavouredArticlesCache.clear(); } getUserFavouredArticles(userId, callback); } @Override public void getMoreUserFavouredArticles(String userId, LoadCallback<Article> callback) { getUserFavouredArticlesFromServer(userId, callback, true); } public Date getLastUserArticleFavourMapCreatedAt() { return mUserArticleFavourMaps.get(mUserArticleFavourMaps.size() - 1).getCreatedAt(); } }