public static ChanReaderRequest newInstance( Loadable loadable, List<Post> cached, Listener<List<Post>> listener, ErrorListener errorListener) { String url; if (loadable.isBoardMode()) { url = ChanUrls.getPageUrl(loadable.board, loadable.no); } else if (loadable.isThreadMode()) { url = ChanUrls.getThreadUrl(loadable.board, loadable.no); } else if (loadable.isCatalogMode()) { url = ChanUrls.getCatalogUrl(loadable.board); } else { throw new IllegalArgumentException("Unknown mode"); } ChanReaderRequest request = new ChanReaderRequest(url, listener, errorListener); // Copy the loadable and cached list. The cached array may changed/cleared by other threads. request.loadable = loadable.copy(); request.cached = new ArrayList<>(cached); return request; }
@Override public List<Post> readJson(JsonReader reader) throws Exception { List<Post> list; if (loadable.isBoardMode()) { list = loadBoard(reader); } else if (loadable.isThreadMode()) { list = loadThread(reader); } else if (loadable.isCatalogMode()) { list = loadCatalog(reader); } else { throw new IllegalArgumentException("Unknown mode"); } return processPosts(list); }
private List<Post> processPosts(List<Post> serverList) throws Exception { List<Post> totalList = new ArrayList<>(serverList.size()); if (cached.size() > 0) { totalList.addAll(cached); // If there's a cached post but it's not in the list received from the server, mark it as // deleted if (loadable.isThreadMode()) { boolean serverHas; for (Post cache : cached) { serverHas = false; for (Post b : serverList) { if (b.no == cache.no) { serverHas = true; break; } } cache.deleted = !serverHas; } } // If there's a post in the list from the server, that's not in the cached list, add it. boolean known; for (Post post : serverList) { known = false; for (Post cache : cached) { if (cache.no == post.no) { known = true; break; } } // serverPost is not in finalList if (!known) { totalList.add(post); } } // Sort if it got out of order due to posts disappearing/reappearing /*if (loadable.isThreadMode()) { Collections.sort(totalList, new Comparator<Post>() { @Override public int compare(Post lhs, Post rhs) { return lhs.time == rhs.time ? 0 : (lhs.time < rhs.time ? -1 : 1); } }); }*/ } else { totalList.addAll(serverList); } Set<Integer> invalidatedPosts = new HashSet<>(); for (Post post : totalList) { if (!post.deleted) { post.repliesFrom.clear(); for (Post other : totalList) { if (other.repliesTo.contains(post.no) && !other.deleted) { post.repliesFrom.add(other.no); } } } else { post.repliesTo.clear(); for (int no : post.repliesFrom) { invalidatedPosts.add(no); } post.repliesFrom.clear(); } } for (int no : invalidatedPosts) { for (Post post : totalList) { if (post.no == no) { if (!post.finish()) { throw new IOException("Incorrect data about post received."); } break; } } } for (Post post : totalList) { post.isSavedReply = ChanApplication.getDatabaseManager().isSavedReply(post.board, post.no); } return totalList; }