From fe352c516fb6dedfeac5d6b2574569ee9b479b98 Mon Sep 17 00:00:00 2001 From: Floens Date: Sun, 26 Jul 2015 12:04:03 +0200 Subject: [PATCH] Add PostStubCell, for either list or card mode. --- .../java/org/floens/chan/chan/ChanParser.java | 15 +- .../chan/core/manager/FilterEngine.java | 5 +- .../chan/core/net/ChanReaderRequest.java | 11 +- .../floens/chan/ui/adapter/PostAdapter.java | 24 ++- .../org/floens/chan/ui/cell/CardPostCell.java | 12 +- .../org/floens/chan/ui/cell/PostCell.java | 12 +- .../chan/ui/cell/PostCellInterface.java | 2 +- .../org/floens/chan/ui/cell/PostStubCell.java | 197 ++++++++++++++++++ .../ui/controller/MainSettingsController.java | 1 + .../ui/controller/PostRepliesController.java | 2 +- .../controller/ThemeSettingsController.java | 3 +- .../src/main/res/layout/cell_post_stub.xml | 62 ++++++ 12 files changed, 314 insertions(+), 32 deletions(-) create mode 100644 Clover/app/src/main/java/org/floens/chan/ui/cell/PostStubCell.java create mode 100644 Clover/app/src/main/res/layout/cell_post_stub.xml diff --git a/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java b/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java index 4f13f147..8e935e37 100644 --- a/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java +++ b/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java @@ -30,10 +30,10 @@ import android.text.style.TypefaceSpan; import android.text.style.UnderlineSpan; import org.floens.chan.Chan; +import org.floens.chan.core.database.DatabaseManager; import org.floens.chan.core.model.Post; import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.settings.ChanSettings; -import org.floens.chan.core.database.DatabaseManager; import org.floens.chan.ui.theme.Theme; import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.utils.Logger; @@ -102,6 +102,14 @@ public class ChanParser { } } + /** + * Parse the comment, subject, tripcodes, names etc. as spannables.
+ * This is done on a background thread for performance, even when it is UI code.
+ * The results will be placed on the Post.*Span members. + * + * @param theme Theme to use for parsing + * @param post Post to get data from + */ private void parseSpans(Theme theme, Post post) { boolean anonymize = ChanSettings.anonymize.get(); boolean anonymizeIds = ChanSettings.anonymizeIds.get(); @@ -119,7 +127,10 @@ public class ChanParser { if (!TextUtils.isEmpty(post.subject)) { post.subjectSpan = new SpannableString(post.subject); - post.subjectSpan.setSpan(new ForegroundColorSpan(theme.subjectColor), 0, post.subjectSpan.length(), 0); + // Do not set another color when the post is in stub mode, it sets text_color_secondary + if (!post.filterStub) { + post.subjectSpan.setSpan(new ForegroundColorSpan(theme.subjectColor), 0, post.subjectSpan.length(), 0); + } } if (!TextUtils.isEmpty(post.name) && !post.name.equals("Anonymous")) { diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java b/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java index c8189d20..f626a625 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java @@ -148,6 +148,7 @@ public class FilterEngine { } public boolean matches(Filter filter, Post post) { + // Post has not been finish()ed yet, account for invalid values String text = null; FilterType type = FilterType.forId(filter.type); switch (type) { @@ -158,7 +159,7 @@ public class FilterEngine { text = post.name; break; case COMMENT: - text = post.comment.toString(); + text = post.comment == null ? null : post.comment.toString(); break; case ID: text = post.id; @@ -171,7 +172,7 @@ public class FilterEngine { break; } - return matches(filter, text, false); + return !TextUtils.isEmpty(text) && matches(filter, text, false); } public boolean matches(Filter filter, String text, boolean forceCompile) { 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 7ad356a8..c97f2de2 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 @@ -318,11 +318,12 @@ public class ChanReaderRequest extends JsonReaderRequest { private static final int TYPE_POST = 0; private static final int TYPE_STATUS = 1; + private static final int TYPE_POST_STUB = 2; private final PostAdapterCallback postAdapterCallback; private final PostCellInterface.PostCellCallback postCellCallback; @@ -76,6 +77,8 @@ public class PostAdapter extends RecyclerView.Adapter { PostCellInterface postCell = (PostCellInterface) LayoutInflater.from(parent.getContext()).inflate(layout, parent, false); return new PostViewHolder(postCell); + } else if (viewType == TYPE_POST_STUB) { + return new PostViewHolder((PostCellInterface) LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_post_stub, parent, false)); } else { StatusViewHolder statusViewHolder = new StatusViewHolder((ThreadStatusCell) LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_thread_status, parent, false)); statusViewHolder.threadStatusCell.setCallback(statusCellCallback); @@ -86,12 +89,13 @@ public class PostAdapter extends RecyclerView.Adapter { @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - if (getItemViewType(position) == TYPE_POST) { + int itemViewType = getItemViewType(position); + if (itemViewType == TYPE_POST || itemViewType == TYPE_POST_STUB) { PostViewHolder postViewHolder = (PostViewHolder) holder; Post post = displayList.get(position); boolean highlight = post == highlightedPost || post.id.equals(highlightedPostId) || post.no == highlightedPostNo || post.tripcode.equals(highlightedPostTripcode); - postViewHolder.postView.setPost(null, post, postCellCallback, highlight, -1); - } else if (getItemViewType(position) == TYPE_STATUS) { + postViewHolder.postView.setPost(null, post, postCellCallback, highlight, -1, postViewMode); + } else if (itemViewType == TYPE_STATUS) { ((StatusViewHolder) holder).threadStatusCell.update(); onScrolledToBottom(); } @@ -108,20 +112,22 @@ public class PostAdapter extends RecyclerView.Adapter { @Override public int getItemViewType(int position) { - if (showStatusView()) { - if (position == getItemCount() - 1) { - return TYPE_STATUS; + if (showStatusView() && position == getItemCount() - 1) { + return TYPE_STATUS; + } else { + Post post = displayList.get(position); + if (post.filterStub) { + return TYPE_POST_STUB; } else { return TYPE_POST; } - } else { - return TYPE_POST; } } @Override public long getItemId(int position) { - if (getItemViewType(position) != TYPE_POST) { + int itemViewType = getItemViewType(position); + if (itemViewType == TYPE_STATUS) { return -1; } else { return displayList.get(position).no; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/CardPostCell.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/CardPostCell.java index 48232f93..29411638 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/CardPostCell.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/CardPostCell.java @@ -55,7 +55,7 @@ public class CardPostCell extends CardView implements PostCellInterface, View.On private FastTextView comment; private TextView replies; private ImageView options; - private View colorLeft; + private View filterMatchColor; public CardPostCell(Context context) { super(context); @@ -80,7 +80,7 @@ public class CardPostCell extends CardView implements PostCellInterface, View.On replies = (TextView) findViewById(R.id.replies); options = (ImageView) findViewById(R.id.options); setRoundItemBackground(options); - colorLeft = findViewById(R.id.filter_match_color); + filterMatchColor = findViewById(R.id.filter_match_color); int textSizeSp = Integer.parseInt(ChanSettings.fontSize.get()); title.setTextSize(textSizeSp); @@ -139,7 +139,7 @@ public class CardPostCell extends CardView implements PostCellInterface, View.On } } - public void setPost(Theme theme, final Post post, PostCellInterface.PostCellCallback callback, boolean highlighted, int markedNo) { + public void setPost(Theme theme, final Post post, PostCellInterface.PostCellCallback callback, boolean highlighted, int markedNo, PostCellInterface.PostViewMode postViewMode) { if (this.post == post) { return; } @@ -186,10 +186,10 @@ public class CardPostCell extends CardView implements PostCellInterface, View.On } if (post.filterHighlightedColor != 0) { - colorLeft.setVisibility(View.VISIBLE); - colorLeft.setBackgroundColor(post.filterHighlightedColor); + filterMatchColor.setVisibility(View.VISIBLE); + filterMatchColor.setBackgroundColor(post.filterHighlightedColor); } else { - colorLeft.setVisibility(View.GONE); + filterMatchColor.setVisibility(View.GONE); } if (!TextUtils.isEmpty(post.subjectSpan)) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java index 18d4ad98..47369087 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java @@ -224,7 +224,7 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin } } - public void setPost(Theme theme, final Post post, PostCellInterface.PostCellCallback callback, boolean highlighted, int markedNo) { + public void setPost(Theme theme, final Post post, PostCellInterface.PostCellCallback callback, boolean highlighted, int markedNo, PostCellInterface.PostViewMode postViewMode) { if (this.post == post && this.highlighted == highlighted && this.markedNo == markedNo) { return; } @@ -291,7 +291,7 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin colorLeft.setVisibility(View.GONE); } - if (post.hasImage && !post.filterStub) { + if (post.hasImage) { thumbnailView.setVisibility(View.VISIBLE); thumbnailView.setUrl(post.thumbnailUrl, thumbnailView.getLayoutParams().width, thumbnailView.getLayoutParams().height); } else { @@ -353,16 +353,14 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin } CharSequence commentText; - if (post.filterStub) { - commentText = null; - } else if (post.comment.length() > COMMENT_MAX_LENGTH_BOARD && !threadMode) { + if (post.comment.length() > COMMENT_MAX_LENGTH_BOARD && !threadMode) { commentText = post.comment.subSequence(0, COMMENT_MAX_LENGTH_BOARD); } else { commentText = post.comment; } comment.setText(commentText); - comment.setVisibility(TextUtils.isEmpty(commentText) ? GONE : VISIBLE); + comment.setVisibility(TextUtils.isEmpty(commentText) && !post.hasImage ? GONE : VISIBLE); if (commentClickable != threadMode) { commentClickable = threadMode; @@ -379,7 +377,7 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin } } - if (!post.filterStub && ((!threadMode && post.replies > 0) || (post.repliesFrom.size() > 0))) { + if ((!threadMode && post.replies > 0) || (post.repliesFrom.size() > 0)) { replies.setVisibility(View.VISIBLE); int replyCount = threadMode ? post.repliesFrom.size() : post.replies; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java index 34df8c56..938005fe 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java @@ -27,7 +27,7 @@ import org.floens.chan.ui.view.ThumbnailView; import java.util.List; public interface PostCellInterface { - void setPost(Theme theme, Post post, PostCellCallback callback, boolean highlighted, int markedN); + void setPost(Theme theme, Post post, PostCellCallback callback, boolean highlighted, int markedNo, PostCellInterface.PostViewMode postViewMode); Post getPost(); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostStubCell.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostStubCell.java new file mode 100644 index 00000000..8d678f2a --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostStubCell.java @@ -0,0 +1,197 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.floens.chan.ui.cell; + +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import org.floens.chan.R; +import org.floens.chan.core.model.Post; +import org.floens.chan.core.settings.ChanSettings; +import org.floens.chan.ui.theme.Theme; +import org.floens.chan.ui.theme.ThemeHelper; +import org.floens.chan.ui.view.FloatingMenu; +import org.floens.chan.ui.view.FloatingMenuItem; +import org.floens.chan.ui.view.ThumbnailView; + +import java.util.ArrayList; +import java.util.List; + +import static org.floens.chan.utils.AndroidUtils.dp; +import static org.floens.chan.utils.AndroidUtils.setRoundItemBackground; + +public class PostStubCell extends RelativeLayout implements PostCellInterface, View.OnClickListener { + private static final int TITLE_MAX_LENGTH = 100; + + private boolean bound; + private Theme theme; + private Post post; + private PostViewMode postViewMode; + private PostCellInterface.PostCellCallback callback; + + private TextView title; + private ImageView options; + private View divider; + + public PostStubCell(Context context) { + super(context); + } + + public PostStubCell(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public PostStubCell(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + title = (TextView) findViewById(R.id.title); + options = (ImageView) findViewById(R.id.options); + setRoundItemBackground(options); + divider = findViewById(R.id.divider); + + int textSizeSp = Integer.parseInt(ChanSettings.fontSize.get()); + title.setTextSize(textSizeSp); + + int paddingPx = dp(textSizeSp - 6); + title.setPadding(paddingPx, 0, 0, 0); + + RelativeLayout.LayoutParams dividerParams = (RelativeLayout.LayoutParams) divider.getLayoutParams(); + dividerParams.leftMargin = paddingPx; + dividerParams.rightMargin = paddingPx; + divider.setLayoutParams(dividerParams); + + setOnClickListener(this); + + options.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + List items = new ArrayList<>(); + + callback.onPopulatePostOptions(post, items); + + FloatingMenu menu = new FloatingMenu(getContext(), v, items); + menu.setCallback(new FloatingMenu.FloatingMenuCallback() { + @Override + public void onFloatingMenuItemClicked(FloatingMenu menu, FloatingMenuItem item) { + callback.onPostOptionClicked(post, item.getId()); + } + + @Override + public void onFloatingMenuDismissed(FloatingMenu menu) { + } + }); + menu.show(); + } + }); + } + + @Override + public void onClick(View v) { + if (v == this) { + callback.onPostClicked(post); + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + if (post != null && bound) { + unbindPost(post); + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + if (post != null && !bound) { + bindPost(theme, post); + } + } + + public void setPost(Theme theme, final Post post, PostCellInterface.PostCellCallback callback, boolean highlighted, int markedNo, PostCellInterface.PostViewMode postViewMode) { + if (this.post == post) { + return; + } + + if (theme == null) { + theme = ThemeHelper.theme(); + } + + if (this.post != null && bound) { + unbindPost(this.post); + this.post = null; + } + + this.theme = theme; + this.post = post; + this.callback = callback; + this.postViewMode = postViewMode; + + bindPost(theme, post); + } + + public Post getPost() { + return post; + } + + public ThumbnailView getThumbnailView() { + return null; + } + + @Override + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + public boolean hasOverlappingRendering() { + return false; + } + + private void bindPost(Theme theme, Post post) { + bound = true; + + if (!TextUtils.isEmpty(post.subjectSpan)) { + title.setText(post.subjectSpan); + } else { + CharSequence titleText; + if (post.comment.length() > TITLE_MAX_LENGTH) { + titleText = post.comment.subSequence(0, TITLE_MAX_LENGTH); + } else { + titleText = post.comment; + } + title.setText(titleText); + } + + divider.setVisibility(postViewMode == PostViewMode.CARD ? GONE : VISIBLE); + } + + private void unbindPost(Post post) { + bound = false; + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java index 8657ff52..c39e3d08 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java @@ -195,6 +195,7 @@ public class MainSettingsController extends SettingsController implements Toolba public void onClick(View v) { Chan.getDatabaseManager().clearAllThreadHides(); Toast.makeText(context, R.string.setting_cleared_thread_hides, Toast.LENGTH_LONG).show(); + EventBus.getDefault().post(new RefreshUIMessage("clearhides")); } })); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java index 65e4b31c..2337ee1f 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java @@ -177,7 +177,7 @@ public class PostRepliesController extends Controller { } final Post p = getItem(position); - postCell.setPost(null, p, presenter, false, data.forPost.no); + postCell.setPost(null, p, presenter, false, data.forPost.no, PostCellInterface.PostViewMode.LIST); return (View) postCell; } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java index 6af83585..1adf0fa4 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java @@ -40,6 +40,7 @@ import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.ui.activity.StartActivity; import org.floens.chan.ui.cell.PostCell; +import org.floens.chan.ui.cell.PostCellInterface; import org.floens.chan.ui.theme.Theme; import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.ui.toolbar.NavigationItem; @@ -252,7 +253,7 @@ public class ThemeSettingsController extends Controller implements View.OnClickL themeContext.getResources().getDimensionPixelSize(R.dimen.toolbar_height))); PostCell postCell = (PostCell) LayoutInflater.from(themeContext).inflate(R.layout.cell_post, null); - postCell.setPost(theme, post, DUMMY_POST_CALLBACK, false, -1); + postCell.setPost(theme, post, DUMMY_POST_CALLBACK, false, -1, PostCellInterface.PostViewMode.LIST); linearLayout.addView(postCell, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); return linearLayout; diff --git a/Clover/app/src/main/res/layout/cell_post_stub.xml b/Clover/app/src/main/res/layout/cell_post_stub.xml new file mode 100644 index 00000000..55d33272 --- /dev/null +++ b/Clover/app/src/main/res/layout/cell_post_stub.xml @@ -0,0 +1,62 @@ + + + + + + + + + +