diff --git a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java index 11218985..7eaffa87 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java +++ b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java @@ -77,6 +77,7 @@ public class Post { public String title = ""; public int fileSize; public int images = -1; + public boolean deleted = false; /** * This post replies to the these ids diff --git a/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java b/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java index 4c6e6806..b140e99e 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java +++ b/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java @@ -32,7 +32,9 @@ import org.floens.chan.core.model.Post; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class ChanReaderRequest extends JsonReaderRequest> { private Loadable loadable; @@ -82,25 +84,94 @@ public class ChanReaderRequest extends JsonReaderRequest> { throw new IllegalArgumentException("Unknown mode"); } - processPosts(list); - - return list; + List result = null; + try { + result = processPosts(list); + } catch (IOException e) { + setError(new ParseError(e)); + } + return result; } - private void processPosts(List posts) { + private List processPosts(List serverList) throws IOException { boolean anonymize = ChanPreferences.getAnonymize(); boolean anonymizeIds = ChanPreferences.getAnonymizeIds(); String name = ChanApplication.getInstance().getString(R.string.default_name); - for (Post post : posts) { - post.repliesFrom.clear(); + List 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 + boolean serverHas; + for (Post cache : cached) { + serverHas = false; + for (Post b : serverList) { + if (b.no == cache.no) { + serverHas = true; + break; + } + } + + if (!serverHas) + cache.deleted = true; + } + + // 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); + } + } + } else { + totalList.addAll(serverList); + } + + Set invalidatedPosts = new HashSet<>(); + for (Post post : totalList) { + if (!post.deleted) { + post.repliesFrom.clear(); - for (Post other : posts) { - if (other.repliesTo.contains(post.no)) { - post.repliesFrom.add(other.no); + 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(loadable)) { + throw new IOException("Incorrect data about post received."); + } + break; + } + } + } + for (Post post : totalList) { post.isSavedReply = ChanApplication.getDatabaseManager().isSavedReply(post.board, post.no); if (anonymize) { @@ -113,6 +184,8 @@ public class ChanReaderRequest extends JsonReaderRequest> { post.id = ""; } } + + return totalList; } private List loadThread(JsonReader reader) { diff --git a/Clover/app/src/main/java/org/floens/chan/core/net/JsonReaderRequest.java b/Clover/app/src/main/java/org/floens/chan/core/net/JsonReaderRequest.java index c0090205..0cc1e970 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/net/JsonReaderRequest.java +++ b/Clover/app/src/main/java/org/floens/chan/core/net/JsonReaderRequest.java @@ -67,7 +67,7 @@ public abstract class JsonReaderRequest extends Request { e.printStackTrace(); } - if (read == null) { + if (read == null && error == null) { return Response.error(new VolleyError()); } else if (error != null) { return Response.error(error); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java index 7e5bc7ee..74fde222 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java @@ -80,6 +80,7 @@ public class PostView extends LinearLayout implements View.OnClickListener { private LinearLayout iconsView; private ImageView stickyView; private ImageView closedView; + private ImageView deletedView; private NetworkImageView countryView; private ImageView optionsView; private View lastSeen; @@ -241,11 +242,13 @@ public class PostView extends LinearLayout implements View.OnClickListener { boolean showCountryFlag = isList() && !TextUtils.isEmpty(post.country); boolean showStickyIcon = isList() && post.sticky; boolean showClosedIcon = isList() && post.closed; + boolean showDeletedIcon = isList() && post.deleted; - iconsView.setVisibility((showCountryFlag || showStickyIcon || showClosedIcon) ? View.VISIBLE : View.GONE); + iconsView.setVisibility((showCountryFlag || showStickyIcon || showClosedIcon || showDeletedIcon) ? View.VISIBLE : View.GONE); stickyView.setVisibility(showStickyIcon ? View.VISIBLE : View.GONE); closedView.setVisibility(showClosedIcon ? View.VISIBLE : View.GONE); + deletedView.setVisibility(showDeletedIcon ? View.VISIBLE : View.GONE); if (showCountryFlag) { countryView.setVisibility(View.VISIBLE); countryView.setImageUrl(ChanUrls.getCountryFlagUrl(post.country), ChanApplication.getImageLoader()); @@ -422,6 +425,10 @@ public class PostView extends LinearLayout implements View.OnClickListener { closedView.setImageBitmap(IconCache.closedIcon); iconsView.addView(closedView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); + deletedView = new ImageView(context); + deletedView.setImageBitmap(IconCache.trashIcon); + iconsView.addView(deletedView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); + countryView = new NetworkImageView(context); countryView.setScaleType(ImageView.ScaleType.FIT_CENTER); iconsView.addView(countryView, new LinearLayout.LayoutParams(iconWidth, iconHeight)); diff --git a/Clover/app/src/main/java/org/floens/chan/utils/IconCache.java b/Clover/app/src/main/java/org/floens/chan/utils/IconCache.java index e6530d2a..57189ec0 100644 --- a/Clover/app/src/main/java/org/floens/chan/utils/IconCache.java +++ b/Clover/app/src/main/java/org/floens/chan/utils/IconCache.java @@ -26,19 +26,11 @@ import org.floens.chan.R; public class IconCache { public static Bitmap stickyIcon; public static Bitmap closedIcon; + public static Bitmap trashIcon; - /** - * Load the icons in the cache. Lightweight icons only! Icons can be null! - * - * @param context - */ public static void createIcons(final Context context) { - new Thread(new Runnable() { - @Override - public void run() { - stickyIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.sticky_icon); - closedIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.closed_icon); - } - }).start(); + stickyIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.sticky_icon); + closedIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.closed_icon); + trashIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.trash_icon); } } diff --git a/Clover/app/src/main/res/drawable-mdpi/closed_icon.png b/Clover/app/src/main/res/drawable-mdpi/closed_icon.png index 565fc938..d9939afc 100644 Binary files a/Clover/app/src/main/res/drawable-mdpi/closed_icon.png and b/Clover/app/src/main/res/drawable-mdpi/closed_icon.png differ diff --git a/Clover/app/src/main/res/drawable-mdpi/sticky_icon.png b/Clover/app/src/main/res/drawable-mdpi/sticky_icon.png index c6eabaf2..9fe9f8b2 100644 Binary files a/Clover/app/src/main/res/drawable-mdpi/sticky_icon.png and b/Clover/app/src/main/res/drawable-mdpi/sticky_icon.png differ diff --git a/Clover/app/src/main/res/drawable-mdpi/trash_icon.png b/Clover/app/src/main/res/drawable-mdpi/trash_icon.png new file mode 100644 index 00000000..fc26e66e Binary files /dev/null and b/Clover/app/src/main/res/drawable-mdpi/trash_icon.png differ