|
|
@ -11,9 +11,11 @@ import android.os.Build; |
|
|
|
import android.os.Bundle; |
|
|
|
import android.support.annotation.NonNull; |
|
|
|
import android.support.v4.content.res.ResourcesCompat; |
|
|
|
import android.support.v7.widget.AppCompatImageButton; |
|
|
|
import android.support.v7.widget.CardView; |
|
|
|
import android.support.v7.widget.RecyclerView; |
|
|
|
import android.text.TextUtils; |
|
|
|
import android.util.Log; |
|
|
|
import android.view.LayoutInflater; |
|
|
|
import android.view.MotionEvent; |
|
|
|
import android.view.View; |
|
|
@ -21,6 +23,7 @@ import android.view.ViewGroup; |
|
|
|
import android.webkit.WebResourceRequest; |
|
|
|
import android.webkit.WebView; |
|
|
|
import android.webkit.WebViewClient; |
|
|
|
import android.widget.EditText; |
|
|
|
import android.widget.FrameLayout; |
|
|
|
import android.widget.ImageButton; |
|
|
|
import android.widget.ImageView; |
|
|
@ -31,6 +34,7 @@ import android.widget.TextView; |
|
|
|
import com.squareup.picasso.Picasso; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Objects; |
|
|
|
|
|
|
@ -50,12 +54,11 @@ import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; |
|
|
|
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; |
|
|
|
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; |
|
|
|
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; |
|
|
|
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList; |
|
|
|
|
|
|
|
/** |
|
|
|
* Custom {@link android.support.v7.widget.RecyclerView.Adapter} used for topics. |
|
|
|
*/ |
|
|
|
class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> { |
|
|
|
class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { |
|
|
|
/** |
|
|
|
* Debug Tag for logging debug output to LogCat |
|
|
|
*/ |
|
|
@ -65,6 +68,7 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> { |
|
|
|
*/ |
|
|
|
private static int THUMBNAIL_SIZE; |
|
|
|
private final Context context; |
|
|
|
private ArrayList<Integer> toQuoteList = new ArrayList<>(); |
|
|
|
private final List<Post> postsList; |
|
|
|
/** |
|
|
|
* Used to hold the state of visibility and other attributes for views that are animated or |
|
|
@ -87,69 +91,16 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> { |
|
|
|
*/ |
|
|
|
private static final int isQuoteButtonChecked = 2; |
|
|
|
private TopicActivity.TopicTask topicTask; |
|
|
|
|
|
|
|
/** |
|
|
|
* Custom {@link RecyclerView.ViewHolder} implementation |
|
|
|
*/ |
|
|
|
class MyViewHolder extends RecyclerView.ViewHolder { |
|
|
|
final CardView cardView; |
|
|
|
final LinearLayout cardChildLinear; |
|
|
|
final FrameLayout postDateAndNumberExp; |
|
|
|
final TextView postDate, postNum, username, subject; |
|
|
|
final ImageView thumbnail; |
|
|
|
final public WebView post; |
|
|
|
final ImageButton quoteToggle; |
|
|
|
final RelativeLayout header; |
|
|
|
final LinearLayout userExtraInfo; |
|
|
|
final View bodyFooterDivider; |
|
|
|
final LinearLayout postFooter; |
|
|
|
|
|
|
|
final TextView specialRank, rank, gender, numberOfPosts, personalText, stars; |
|
|
|
|
|
|
|
MyViewHolder(View view) { |
|
|
|
super(view); |
|
|
|
//Initializes layout's graphic elements
|
|
|
|
//Standard stuff
|
|
|
|
cardView = (CardView) view.findViewById(R.id.card_view); |
|
|
|
cardChildLinear = (LinearLayout) view.findViewById(R.id.card_child_linear); |
|
|
|
postDateAndNumberExp = (FrameLayout) view.findViewById(R.id.post_date_and_number_exp); |
|
|
|
postDate = (TextView) view.findViewById(R.id.post_date); |
|
|
|
postNum = (TextView) view.findViewById(R.id.post_number); |
|
|
|
thumbnail = (ImageView) view.findViewById(R.id.thumbnail); |
|
|
|
username = (TextView) view.findViewById(R.id.username); |
|
|
|
subject = (TextView) view.findViewById(R.id.subject); |
|
|
|
post = (WebView) view.findViewById(R.id.post); |
|
|
|
post.setBackgroundColor(Color.argb(1, 255, 255, 255)); |
|
|
|
quoteToggle = (ImageButton) view.findViewById(R.id.toggle_quote_button); |
|
|
|
bodyFooterDivider = view.findViewById(R.id.body_footer_divider); |
|
|
|
postFooter = (LinearLayout) view.findViewById(R.id.post_footer); |
|
|
|
|
|
|
|
//User's extra info
|
|
|
|
header = (RelativeLayout) view.findViewById(R.id.header); |
|
|
|
userExtraInfo = (LinearLayout) view.findViewById(R.id.user_extra_info); |
|
|
|
specialRank = (TextView) view.findViewById(R.id.special_rank); |
|
|
|
rank = (TextView) view.findViewById(R.id.rank); |
|
|
|
gender = (TextView) view.findViewById(R.id.gender); |
|
|
|
numberOfPosts = (TextView) view.findViewById(R.id.number_of_posts); |
|
|
|
personalText = (TextView) view.findViewById(R.id.personal_text); |
|
|
|
stars = (TextView) view.findViewById(R.id.stars); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Cancels all pending Picasso requests |
|
|
|
*/ |
|
|
|
void cleanup() { |
|
|
|
Picasso.with(context).cancelRequest(thumbnail); |
|
|
|
thumbnail.setImageDrawable(null); |
|
|
|
} |
|
|
|
} |
|
|
|
private TopicActivity.ReplyTask replyTask; |
|
|
|
private final int VIEW_TYPE_POST = 0; |
|
|
|
private final int VIEW_TYPE_QUICK_REPLY = 1; |
|
|
|
private boolean firstTime = false; |
|
|
|
|
|
|
|
/** |
|
|
|
* @param context the context of the {@link RecyclerView} |
|
|
|
* @param postsList List of {@link Post} objects to use |
|
|
|
*/ |
|
|
|
TopicAdapter(Context context, List<Post> postsList, |
|
|
|
TopicActivity.TopicTask topicTask) { |
|
|
|
TopicAdapter(Context context, List<Post> postsList, TopicActivity.TopicTask topicTask) { |
|
|
|
this.context = context; |
|
|
|
this.postsList = postsList; |
|
|
|
|
|
|
@ -161,280 +112,322 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> { |
|
|
|
this.topicTask = topicTask; |
|
|
|
} |
|
|
|
|
|
|
|
void prepareForReply(TopicActivity.ReplyTask replyTask) { |
|
|
|
this.replyTask = replyTask; |
|
|
|
firstTime = true; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onViewRecycled(final MyViewHolder holder) { |
|
|
|
holder.cleanup(); |
|
|
|
public int getItemViewType(int position) { |
|
|
|
return postsList.get(position) == null ? VIEW_TYPE_QUICK_REPLY : VIEW_TYPE_POST; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { |
|
|
|
View itemView = LayoutInflater.from(parent.getContext()) |
|
|
|
.inflate(R.layout.activity_topic_post_row, parent, false); |
|
|
|
return new MyViewHolder(itemView); |
|
|
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { |
|
|
|
if (viewType == VIEW_TYPE_POST) { |
|
|
|
View itemView = LayoutInflater.from(parent.getContext()) |
|
|
|
.inflate(R.layout.activity_topic_post_row, parent, false); |
|
|
|
return new PostViewHolder(itemView); |
|
|
|
} else if (viewType == VIEW_TYPE_QUICK_REPLY) { |
|
|
|
View view = LayoutInflater.from(parent.getContext()). |
|
|
|
inflate(R.layout.activity_topic_quick_reply_row, parent, false); |
|
|
|
return new QuickReplyViewHolder(view); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
@SuppressLint("SetJavaScriptEnabled") |
|
|
|
@Override |
|
|
|
public void onBindViewHolder(final MyViewHolder holder, final int position) { |
|
|
|
final Post currentPost = postsList.get(position); |
|
|
|
|
|
|
|
//Post's WebView parameters
|
|
|
|
holder.post.setClickable(true); |
|
|
|
holder.post.setWebViewClient(new LinkLauncher()); |
|
|
|
|
|
|
|
//Avoids errors about layout having 0 width/height
|
|
|
|
holder.thumbnail.setMinimumWidth(1); |
|
|
|
holder.thumbnail.setMinimumHeight(1); |
|
|
|
//Sets thumbnail size
|
|
|
|
holder.thumbnail.setMaxWidth(THUMBNAIL_SIZE); |
|
|
|
holder.thumbnail.setMaxHeight(THUMBNAIL_SIZE); |
|
|
|
|
|
|
|
//noinspection ConstantConditions
|
|
|
|
Picasso.with(context) |
|
|
|
.load(currentPost.getThumbnailUrl()) |
|
|
|
.resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE) |
|
|
|
.centerCrop() |
|
|
|
.error(ResourcesCompat.getDrawable(context.getResources() |
|
|
|
, R.drawable.ic_default_user_thumbnail, null)) |
|
|
|
.placeholder(ResourcesCompat.getDrawable(context.getResources() |
|
|
|
, R.drawable.ic_default_user_thumbnail, null)) |
|
|
|
.transform(new CircleTransform()) |
|
|
|
.into(holder.thumbnail); |
|
|
|
|
|
|
|
//Sets username,submit date, index number, subject, post's and attached files texts
|
|
|
|
holder.username.setText(currentPost.getAuthor()); |
|
|
|
holder.postDate.setText(currentPost.getPostDate()); |
|
|
|
if (currentPost.getPostNumber() != 0) |
|
|
|
holder.postNum.setText(context.getString( |
|
|
|
R.string.user_number_of_posts, currentPost.getPostNumber())); |
|
|
|
else |
|
|
|
holder.postNum.setText(""); |
|
|
|
holder.subject.setText(currentPost.getSubject()); |
|
|
|
holder.post.loadDataWithBaseURL("file:///android_asset/", currentPost.getContent(), "text/html", "UTF-8", null); |
|
|
|
if (currentPost.getAttachedFiles() != null && currentPost.getAttachedFiles().size() != 0) { |
|
|
|
holder.bodyFooterDivider.setVisibility(View.VISIBLE); |
|
|
|
int filesTextColor; |
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
|
|
|
filesTextColor = context.getResources().getColor(R.color.accent, null); |
|
|
|
} else //noinspection deprecation
|
|
|
|
filesTextColor = context.getResources().getColor(R.color.accent); |
|
|
|
|
|
|
|
holder.postFooter.removeAllViews(); |
|
|
|
for (final ThmmyFile attachedFile : currentPost.getAttachedFiles()) { |
|
|
|
final TextView attached = new TextView(context); |
|
|
|
attached.setTextSize(10f); |
|
|
|
attached.setClickable(true); |
|
|
|
attached.setTypeface(Typeface.createFromAsset(context.getAssets() |
|
|
|
public void onBindViewHolder(final RecyclerView.ViewHolder currentHolder, final int position) { |
|
|
|
if (currentHolder instanceof PostViewHolder) { |
|
|
|
final Post currentPost = postsList.get(position); |
|
|
|
final PostViewHolder holder = (PostViewHolder) currentHolder; |
|
|
|
|
|
|
|
//Post's WebView parameters
|
|
|
|
holder.post.setClickable(true); |
|
|
|
holder.post.setWebViewClient(new LinkLauncher()); |
|
|
|
|
|
|
|
//Avoids errors about layout having 0 width/height
|
|
|
|
holder.thumbnail.setMinimumWidth(1); |
|
|
|
holder.thumbnail.setMinimumHeight(1); |
|
|
|
//Sets thumbnail size
|
|
|
|
holder.thumbnail.setMaxWidth(THUMBNAIL_SIZE); |
|
|
|
holder.thumbnail.setMaxHeight(THUMBNAIL_SIZE); |
|
|
|
|
|
|
|
//noinspection ConstantConditions
|
|
|
|
Picasso.with(context) |
|
|
|
.load(currentPost.getThumbnailUrl()) |
|
|
|
.resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE) |
|
|
|
.centerCrop() |
|
|
|
.error(ResourcesCompat.getDrawable(context.getResources() |
|
|
|
, R.drawable.ic_default_user_thumbnail, null)) |
|
|
|
.placeholder(ResourcesCompat.getDrawable(context.getResources() |
|
|
|
, R.drawable.ic_default_user_thumbnail, null)) |
|
|
|
.transform(new CircleTransform()) |
|
|
|
.into(holder.thumbnail); |
|
|
|
|
|
|
|
//Sets username,submit date, index number, subject, post's and attached files texts
|
|
|
|
holder.username.setText(currentPost.getAuthor()); |
|
|
|
holder.postDate.setText(currentPost.getPostDate()); |
|
|
|
if (currentPost.getPostNumber() != 0) |
|
|
|
holder.postNum.setText(context.getString( |
|
|
|
R.string.user_number_of_posts, currentPost.getPostNumber())); |
|
|
|
else |
|
|
|
holder.postNum.setText(""); |
|
|
|
holder.subject.setText(currentPost.getSubject()); |
|
|
|
holder.post.loadDataWithBaseURL("file:///android_asset/", currentPost.getContent(), "text/html", "UTF-8", null); |
|
|
|
if (currentPost.getAttachedFiles() != null && currentPost.getAttachedFiles().size() != 0) { |
|
|
|
holder.bodyFooterDivider.setVisibility(View.VISIBLE); |
|
|
|
int filesTextColor; |
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
|
|
|
filesTextColor = context.getResources().getColor(R.color.accent, null); |
|
|
|
} else //noinspection deprecation
|
|
|
|
filesTextColor = context.getResources().getColor(R.color.accent); |
|
|
|
|
|
|
|
holder.postFooter.removeAllViews(); |
|
|
|
for (final ThmmyFile attachedFile : currentPost.getAttachedFiles()) { |
|
|
|
final TextView attached = new TextView(context); |
|
|
|
attached.setTextSize(10f); |
|
|
|
attached.setClickable(true); |
|
|
|
attached.setTypeface(Typeface.createFromAsset(context.getAssets() |
|
|
|
, "fonts/fontawesome-webfont.ttf")); |
|
|
|
attached.setText(faIconFromFilename(attachedFile.getFilename()) + " " |
|
|
|
+ attachedFile.getFilename() + attachedFile.getFileInfo()); |
|
|
|
attached.setTextColor(filesTextColor); |
|
|
|
attached.setPadding(0, 3, 0, 3); |
|
|
|
|
|
|
|
attached.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View view) { |
|
|
|
((BaseActivity) context).launchDownloadService(attachedFile); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
holder.postFooter.addView(attached); |
|
|
|
} |
|
|
|
} else { |
|
|
|
holder.bodyFooterDivider.setVisibility(View.GONE); |
|
|
|
holder.postFooter.removeAllViews(); |
|
|
|
} |
|
|
|
|
|
|
|
String mSpecialRank, mRank, mGender, mNumberOfPosts, mPersonalText; |
|
|
|
int mNumberOfStars, mUserColor; |
|
|
|
|
|
|
|
if (!currentPost.isDeleted()) { //Sets user's extra info
|
|
|
|
mSpecialRank = currentPost.getSpecialRank(); |
|
|
|
mRank = currentPost.getRank(); |
|
|
|
mGender = currentPost.getGender(); |
|
|
|
mNumberOfPosts = currentPost.getNumberOfPosts(); |
|
|
|
mPersonalText = currentPost.getPersonalText(); |
|
|
|
mNumberOfStars = currentPost.getNumberOfStars(); |
|
|
|
mUserColor = currentPost.getUserColor(); |
|
|
|
} else { |
|
|
|
mSpecialRank = null; |
|
|
|
mRank = null; |
|
|
|
mGender = null; |
|
|
|
mNumberOfPosts = null; |
|
|
|
mPersonalText = null; |
|
|
|
mNumberOfStars = 0; |
|
|
|
mUserColor = 0; |
|
|
|
} |
|
|
|
|
|
|
|
if (!Objects.equals(mSpecialRank, "") && mSpecialRank != null) { |
|
|
|
holder.specialRank.setText(mSpecialRank); |
|
|
|
holder.specialRank.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.specialRank.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mRank, "") && mRank != null) { |
|
|
|
holder.rank.setText(mRank); |
|
|
|
holder.rank.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.rank.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mGender, "") && mGender != null) { |
|
|
|
holder.gender.setText(mGender); |
|
|
|
holder.gender.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.gender.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mNumberOfPosts, "") && mNumberOfPosts != null) { |
|
|
|
holder.numberOfPosts.setText(mNumberOfPosts); |
|
|
|
holder.numberOfPosts.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.numberOfPosts.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mPersonalText, "") && mPersonalText != null) { |
|
|
|
holder.personalText.setText("\"" + mPersonalText + "\""); |
|
|
|
holder.personalText.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.personalText.setVisibility(View.GONE); |
|
|
|
if (mNumberOfStars > 0) { |
|
|
|
holder.stars.setTypeface(Typeface.createFromAsset(context.getAssets() |
|
|
|
, "fonts/fontawesome-webfont.ttf")); |
|
|
|
attached.setText(faIconFromFilename(attachedFile.getFilename()) + " " |
|
|
|
+ attachedFile.getFilename() + attachedFile.getFileInfo()); |
|
|
|
attached.setTextColor(filesTextColor); |
|
|
|
attached.setPadding(0, 3, 0, 3); |
|
|
|
|
|
|
|
attached.setOnClickListener(new View.OnClickListener() { |
|
|
|
String aStar = context.getResources().getString(R.string.fa_icon_star); |
|
|
|
String usersStars = ""; |
|
|
|
for (int i = 0; i < mNumberOfStars; ++i) { |
|
|
|
usersStars += aStar; |
|
|
|
} |
|
|
|
holder.stars.setText(usersStars); |
|
|
|
holder.stars.setTextColor(mUserColor); |
|
|
|
holder.stars.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.stars.setVisibility(View.GONE); |
|
|
|
//Special card for special member of the month!
|
|
|
|
if (mUserColor == TopicParser.USER_COLOR_PINK) { |
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
|
|
|
holder.cardChildLinear.setBackground(context.getResources(). |
|
|
|
getDrawable(R.drawable.member_of_the_month_card, null)); |
|
|
|
} else //noinspection deprecation
|
|
|
|
holder.cardChildLinear.setBackground(context.getResources(). |
|
|
|
getDrawable(R.drawable.member_of_the_month_card)); |
|
|
|
} else holder.cardChildLinear.setBackground(null); |
|
|
|
|
|
|
|
//Avoid's view's visibility recycling
|
|
|
|
if (!currentPost.isDeleted() && viewProperties.get(position)[isUserExtraInfoVisibile]) { |
|
|
|
holder.userExtraInfo.setVisibility(View.VISIBLE); |
|
|
|
holder.userExtraInfo.setAlpha(1.0f); |
|
|
|
} else { |
|
|
|
holder.userExtraInfo.setVisibility(View.GONE); |
|
|
|
holder.userExtraInfo.setAlpha(0.0f); |
|
|
|
} |
|
|
|
if (!currentPost.isDeleted()) { |
|
|
|
//Sets graphics behavior
|
|
|
|
holder.header.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View view) { |
|
|
|
((BaseActivity) context).launchDownloadService(attachedFile); |
|
|
|
public void onClick(View v) { |
|
|
|
//Clicking an expanded header starts profile activity
|
|
|
|
if (viewProperties.get(holder.getAdapterPosition())[isUserExtraInfoVisibile]) { |
|
|
|
Intent intent = new Intent(context, ProfileActivity.class); |
|
|
|
Bundle extras = new Bundle(); |
|
|
|
extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL()); |
|
|
|
if (currentPost.getThumbnailUrl() == null) |
|
|
|
extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); |
|
|
|
else |
|
|
|
extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, currentPost.getThumbnailUrl()); |
|
|
|
extras.putString(BUNDLE_PROFILE_USERNAME, currentPost.getAuthor()); |
|
|
|
intent.putExtras(extras); |
|
|
|
intent.setFlags(FLAG_ACTIVITY_NEW_TASK); |
|
|
|
context.startActivity(intent); |
|
|
|
} |
|
|
|
|
|
|
|
boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); |
|
|
|
tmp[isUserExtraInfoVisibile] = !tmp[isUserExtraInfoVisibile]; |
|
|
|
viewProperties.set(holder.getAdapterPosition(), tmp); |
|
|
|
TopicAnimations.animateUserExtraInfoVisibility(holder.userExtraInfo); |
|
|
|
} |
|
|
|
}); |
|
|
|
//Clicking the expanded part of a header (the extra info) makes it collapse
|
|
|
|
holder.userExtraInfo.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View v) { |
|
|
|
boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); |
|
|
|
tmp[1] = false; |
|
|
|
viewProperties.set(holder.getAdapterPosition(), tmp); |
|
|
|
|
|
|
|
holder.postFooter.addView(attached); |
|
|
|
TopicAnimations.animateUserExtraInfoVisibility(v); |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
holder.header.setOnClickListener(null); |
|
|
|
holder.userExtraInfo.setOnClickListener(null); |
|
|
|
} |
|
|
|
} else { |
|
|
|
holder.bodyFooterDivider.setVisibility(View.GONE); |
|
|
|
holder.postFooter.removeAllViews(); |
|
|
|
} |
|
|
|
|
|
|
|
String mSpecialRank, mRank, mGender, mNumberOfPosts, mPersonalText; |
|
|
|
int mNumberOfStars, mUserColor; |
|
|
|
|
|
|
|
if (!currentPost.isDeleted()) { //Sets user's extra info
|
|
|
|
mSpecialRank = currentPost.getSpecialRank(); |
|
|
|
mRank = currentPost.getRank(); |
|
|
|
mGender = currentPost.getGender(); |
|
|
|
mNumberOfPosts = currentPost.getNumberOfPosts(); |
|
|
|
mPersonalText = currentPost.getPersonalText(); |
|
|
|
mNumberOfStars = currentPost.getNumberOfStars(); |
|
|
|
mUserColor = currentPost.getUserColor(); |
|
|
|
} else { |
|
|
|
mSpecialRank = null; |
|
|
|
mRank = null; |
|
|
|
mGender = null; |
|
|
|
mNumberOfPosts = null; |
|
|
|
mPersonalText = null; |
|
|
|
mNumberOfStars = 0; |
|
|
|
mUserColor = 0; |
|
|
|
} |
|
|
|
|
|
|
|
if (!Objects.equals(mSpecialRank, "") && mSpecialRank != null) { |
|
|
|
holder.specialRank.setText(mSpecialRank); |
|
|
|
holder.specialRank.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.specialRank.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mRank, "") && mRank != null) { |
|
|
|
holder.rank.setText(mRank); |
|
|
|
holder.rank.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.rank.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mGender, "") && mGender != null) { |
|
|
|
holder.gender.setText(mGender); |
|
|
|
holder.gender.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.gender.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mNumberOfPosts, "") && mNumberOfPosts != null) { |
|
|
|
holder.numberOfPosts.setText(mNumberOfPosts); |
|
|
|
holder.numberOfPosts.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.numberOfPosts.setVisibility(View.GONE); |
|
|
|
if (!Objects.equals(mPersonalText, "") && mPersonalText != null) { |
|
|
|
holder.personalText.setText("\"" + mPersonalText + "\""); |
|
|
|
holder.personalText.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.personalText.setVisibility(View.GONE); |
|
|
|
if (mNumberOfStars > 0) { |
|
|
|
holder.stars.setTypeface(Typeface.createFromAsset(context.getAssets() |
|
|
|
, "fonts/fontawesome-webfont.ttf")); |
|
|
|
|
|
|
|
String aStar = context.getResources().getString(R.string.fa_icon_star); |
|
|
|
String usersStars = ""; |
|
|
|
for (int i = 0; i < mNumberOfStars; ++i) { |
|
|
|
usersStars += aStar; |
|
|
|
//Avoid's view's visibility recycling
|
|
|
|
if (viewProperties.get(position)[isPostDateAndNumberVisibile]) { //Expanded
|
|
|
|
holder.postDateAndNumberExp.setVisibility(View.VISIBLE); |
|
|
|
holder.postDateAndNumberExp.setAlpha(1.0f); |
|
|
|
holder.postDateAndNumberExp.setTranslationY(0); |
|
|
|
|
|
|
|
holder.username.setMaxLines(Integer.MAX_VALUE); |
|
|
|
holder.username.setEllipsize(null); |
|
|
|
|
|
|
|
holder.subject.setTextColor(Color.parseColor("#FFFFFF")); |
|
|
|
holder.subject.setMaxLines(Integer.MAX_VALUE); |
|
|
|
holder.subject.setEllipsize(null); |
|
|
|
} else { //Collapsed
|
|
|
|
holder.postDateAndNumberExp.setVisibility(View.GONE); |
|
|
|
holder.postDateAndNumberExp.setAlpha(0.0f); |
|
|
|
holder.postDateAndNumberExp.setTranslationY(holder.postDateAndNumberExp.getHeight()); |
|
|
|
|
|
|
|
holder.username.setMaxLines(1); |
|
|
|
holder.username.setEllipsize(TextUtils.TruncateAt.END); |
|
|
|
|
|
|
|
holder.subject.setTextColor(Color.parseColor("#757575")); |
|
|
|
holder.subject.setMaxLines(1); |
|
|
|
holder.subject.setEllipsize(TextUtils.TruncateAt.END); |
|
|
|
} |
|
|
|
holder.stars.setText(usersStars); |
|
|
|
holder.stars.setTextColor(mUserColor); |
|
|
|
holder.stars.setVisibility(View.VISIBLE); |
|
|
|
} else |
|
|
|
holder.stars.setVisibility(View.GONE); |
|
|
|
//Special card for special member of the month!
|
|
|
|
if (mUserColor == TopicParser.USER_COLOR_PINK) { |
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
|
|
|
holder.cardChildLinear.setBackground(context.getResources(). |
|
|
|
getDrawable(R.drawable.member_of_the_month_card, null)); |
|
|
|
} else //noinspection deprecation
|
|
|
|
holder.cardChildLinear.setBackground(context.getResources(). |
|
|
|
getDrawable(R.drawable.member_of_the_month_card)); |
|
|
|
} else holder.cardChildLinear.setBackground(null); |
|
|
|
|
|
|
|
//Avoid's view's visibility recycling
|
|
|
|
if (!currentPost.isDeleted() && viewProperties.get(position)[isUserExtraInfoVisibile]) { |
|
|
|
holder.userExtraInfo.setVisibility(View.VISIBLE); |
|
|
|
holder.userExtraInfo.setAlpha(1.0f); |
|
|
|
} else { |
|
|
|
holder.userExtraInfo.setVisibility(View.GONE); |
|
|
|
holder.userExtraInfo.setAlpha(0.0f); |
|
|
|
} |
|
|
|
if (!currentPost.isDeleted()) { |
|
|
|
//Sets graphics behavior
|
|
|
|
holder.header.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View v) { |
|
|
|
//Clicking an expanded header starts profile activity
|
|
|
|
if (viewProperties.get(holder.getAdapterPosition())[isUserExtraInfoVisibile]) { |
|
|
|
Intent intent = new Intent(context, ProfileActivity.class); |
|
|
|
Bundle extras = new Bundle(); |
|
|
|
extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL()); |
|
|
|
if (currentPost.getThumbnailUrl() == null) |
|
|
|
extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); |
|
|
|
else |
|
|
|
extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, currentPost.getThumbnailUrl()); |
|
|
|
extras.putString(BUNDLE_PROFILE_USERNAME, currentPost.getAuthor()); |
|
|
|
intent.putExtras(extras); |
|
|
|
intent.setFlags(FLAG_ACTIVITY_NEW_TASK); |
|
|
|
context.startActivity(intent); |
|
|
|
//noinspection PointlessBooleanExpression,ConstantConditions
|
|
|
|
if (!BaseActivity.getSessionManager().isLoggedIn() || true) //Hide it until reply is implemented
|
|
|
|
holder.quoteToggle.setVisibility(View.GONE); |
|
|
|
else { |
|
|
|
if (viewProperties.get(position)[isQuoteButtonChecked]) |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked); |
|
|
|
else |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked); |
|
|
|
//Sets graphics behavior
|
|
|
|
holder.quoteToggle.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View view) { |
|
|
|
boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); |
|
|
|
if (tmp[isQuoteButtonChecked]) { |
|
|
|
if (toQuoteList.contains(currentPost.getPostNumber())) { |
|
|
|
toQuoteList.remove(toQuoteList.indexOf(currentPost.getPostNumber())); |
|
|
|
} else |
|
|
|
Report.i(TAG, "An error occurred while trying to exclude post from" + |
|
|
|
"toQuoteList, post wasn't there!"); |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked); |
|
|
|
} else { |
|
|
|
toQuoteList.add(currentPost.getPostNumber()); |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked); |
|
|
|
} |
|
|
|
tmp[isQuoteButtonChecked] = !tmp[isQuoteButtonChecked]; |
|
|
|
viewProperties.set(holder.getAdapterPosition(), tmp); |
|
|
|
} |
|
|
|
|
|
|
|
boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); |
|
|
|
tmp[isUserExtraInfoVisibile] = !tmp[isUserExtraInfoVisibile]; |
|
|
|
viewProperties.set(holder.getAdapterPosition(), tmp); |
|
|
|
TopicAnimations.animateUserExtraInfoVisibility(holder.userExtraInfo); |
|
|
|
} |
|
|
|
}); |
|
|
|
//Clicking the expanded part of a header (the extra info) makes it collapse
|
|
|
|
holder.userExtraInfo.setOnClickListener(new View.OnClickListener() { |
|
|
|
}); |
|
|
|
} |
|
|
|
//Card expand/collapse when card is touched
|
|
|
|
holder.cardView.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View v) { |
|
|
|
public void onClick(View view) { |
|
|
|
//Change post's viewProperties accordingly
|
|
|
|
boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); |
|
|
|
tmp[1] = false; |
|
|
|
tmp[isPostDateAndNumberVisibile] = !tmp[isPostDateAndNumberVisibile]; |
|
|
|
viewProperties.set(holder.getAdapterPosition(), tmp); |
|
|
|
|
|
|
|
TopicAnimations.animateUserExtraInfoVisibility(v); |
|
|
|
TopicAnimations.animatePostExtraInfoVisibility(holder.postDateAndNumberExp |
|
|
|
, holder.username, holder.subject |
|
|
|
, Color.parseColor("#FFFFFF") |
|
|
|
, Color.parseColor("#757575")); |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
holder.header.setOnClickListener(null); |
|
|
|
holder.userExtraInfo.setOnClickListener(null); |
|
|
|
} |
|
|
|
|
|
|
|
//Avoid's view's visibility recycling
|
|
|
|
if (viewProperties.get(position)[isPostDateAndNumberVisibile]) { //Expanded
|
|
|
|
holder.postDateAndNumberExp.setVisibility(View.VISIBLE); |
|
|
|
holder.postDateAndNumberExp.setAlpha(1.0f); |
|
|
|
holder.postDateAndNumberExp.setTranslationY(0); |
|
|
|
|
|
|
|
holder.username.setMaxLines(Integer.MAX_VALUE); |
|
|
|
holder.username.setEllipsize(null); |
|
|
|
|
|
|
|
holder.subject.setTextColor(Color.parseColor("#FFFFFF")); |
|
|
|
holder.subject.setMaxLines(Integer.MAX_VALUE); |
|
|
|
holder.subject.setEllipsize(null); |
|
|
|
} else { //Collapsed
|
|
|
|
holder.postDateAndNumberExp.setVisibility(View.GONE); |
|
|
|
holder.postDateAndNumberExp.setAlpha(0.0f); |
|
|
|
holder.postDateAndNumberExp.setTranslationY(holder.postDateAndNumberExp.getHeight()); |
|
|
|
|
|
|
|
holder.username.setMaxLines(1); |
|
|
|
holder.username.setEllipsize(TextUtils.TruncateAt.END); |
|
|
|
|
|
|
|
holder.subject.setTextColor(Color.parseColor("#757575")); |
|
|
|
holder.subject.setMaxLines(1); |
|
|
|
holder.subject.setEllipsize(TextUtils.TruncateAt.END); |
|
|
|
} |
|
|
|
//noinspection PointlessBooleanExpression,ConstantConditions
|
|
|
|
if (!BaseActivity.getSessionManager().isLoggedIn() || true) //Hide it until reply is implemented
|
|
|
|
holder.quoteToggle.setVisibility(View.GONE); |
|
|
|
else { |
|
|
|
if (viewProperties.get(position)[isQuoteButtonChecked]) |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked); |
|
|
|
else |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked); |
|
|
|
//Sets graphics behavior
|
|
|
|
holder.quoteToggle.setOnClickListener(new View.OnClickListener() { |
|
|
|
//Also when post is clicked
|
|
|
|
holder.post.setOnTouchListener(new CustomTouchListener(holder.post, holder.cardView)); |
|
|
|
} else if (currentHolder instanceof QuickReplyViewHolder) { |
|
|
|
final QuickReplyViewHolder holder = (QuickReplyViewHolder) currentHolder; |
|
|
|
if (firstTime) { |
|
|
|
//Build quotes
|
|
|
|
String quotes = ""; |
|
|
|
for (int quotePosition : toQuoteList) { |
|
|
|
//Date postDate = new Date();
|
|
|
|
Log.d(TAG, postsList.get(quotePosition).getPostDate()); |
|
|
|
if (postsList.get(quotePosition).getPostIndex() != 0) { |
|
|
|
quotes += "[quote author=" + postsList.get(quotePosition).getAuthor() |
|
|
|
+ " link=topic=68525.msg" + postsList.get(quotePosition).getPostIndex() |
|
|
|
+ "#msg" + postsList.get(quotePosition).getPostIndex() |
|
|
|
+ " date=" + "1000" |
|
|
|
+ "\n" + postsList.get(quotePosition).getContent() |
|
|
|
+ "\n" + "[/quote]" + "\n"; |
|
|
|
} |
|
|
|
} |
|
|
|
holder.quickReply.setText(quotes); |
|
|
|
} |
|
|
|
holder.submitButton.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View view) { |
|
|
|
boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); |
|
|
|
if (tmp[isQuoteButtonChecked]) { |
|
|
|
if (toQuoteList.contains(currentPost.getPostNumber())) { |
|
|
|
toQuoteList.remove(toQuoteList.indexOf(currentPost.getPostNumber())); |
|
|
|
} else |
|
|
|
Report.i(TAG, "An error occurred while trying to exclude post from" + |
|
|
|
"toQuoteList, post wasn't there!"); |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked); |
|
|
|
} else { |
|
|
|
toQuoteList.add(currentPost.getPostNumber()); |
|
|
|
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked); |
|
|
|
} |
|
|
|
tmp[isQuoteButtonChecked] = !tmp[isQuoteButtonChecked]; |
|
|
|
viewProperties.set(holder.getAdapterPosition(), tmp); |
|
|
|
if (holder.quickReply.getText().toString().isEmpty()) return; |
|
|
|
holder.submitButton.setEnabled(false); |
|
|
|
replyTask.execute(holder.quickReply.getText().toString()); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
//Card expand/collapse when card is touched
|
|
|
|
holder.cardView.setOnClickListener(new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(View view) { |
|
|
|
//Change post's viewProperties accordingly
|
|
|
|
boolean[] tmp = viewProperties.get(holder.getAdapterPosition()); |
|
|
|
tmp[isPostDateAndNumberVisibile] = !tmp[isPostDateAndNumberVisibile]; |
|
|
|
viewProperties.set(holder.getAdapterPosition(), tmp); |
|
|
|
|
|
|
|
TopicAnimations.animatePostExtraInfoVisibility(holder.postDateAndNumberExp |
|
|
|
, holder.username, holder.subject |
|
|
|
, Color.parseColor("#FFFFFF") |
|
|
|
, Color.parseColor("#757575")); |
|
|
|
} |
|
|
|
}); |
|
|
|
//Also when post is clicked
|
|
|
|
holder.post.setOnTouchListener(new CustomTouchListener(holder.post, holder.cardView)); |
|
|
|
} |
|
|
|
|
|
|
|
void customNotifyDataSetChanged(TopicActivity.TopicTask topicTask) { |
|
|
@ -452,6 +445,68 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> { |
|
|
|
return postsList.size(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Custom {@link RecyclerView.ViewHolder} implementation |
|
|
|
*/ |
|
|
|
private class PostViewHolder extends RecyclerView.ViewHolder { |
|
|
|
final CardView cardView; |
|
|
|
final LinearLayout cardChildLinear; |
|
|
|
final FrameLayout postDateAndNumberExp; |
|
|
|
final TextView postDate, postNum, username, subject; |
|
|
|
final ImageView thumbnail; |
|
|
|
final public WebView post; |
|
|
|
final ImageButton quoteToggle; |
|
|
|
final RelativeLayout header; |
|
|
|
final LinearLayout userExtraInfo; |
|
|
|
final View bodyFooterDivider; |
|
|
|
final LinearLayout postFooter; |
|
|
|
|
|
|
|
final TextView specialRank, rank, gender, numberOfPosts, personalText, stars; |
|
|
|
|
|
|
|
PostViewHolder(View view) { |
|
|
|
super(view); |
|
|
|
//Initializes layout's graphic elements
|
|
|
|
//Standard stuff
|
|
|
|
cardView = (CardView) view.findViewById(R.id.card_view); |
|
|
|
cardChildLinear = (LinearLayout) view.findViewById(R.id.card_child_linear); |
|
|
|
postDateAndNumberExp = (FrameLayout) view.findViewById(R.id.post_date_and_number_exp); |
|
|
|
postDate = (TextView) view.findViewById(R.id.post_date); |
|
|
|
postNum = (TextView) view.findViewById(R.id.post_number); |
|
|
|
thumbnail = (ImageView) view.findViewById(R.id.thumbnail); |
|
|
|
username = (TextView) view.findViewById(R.id.username); |
|
|
|
subject = (TextView) view.findViewById(R.id.subject); |
|
|
|
post = (WebView) view.findViewById(R.id.post); |
|
|
|
post.setBackgroundColor(Color.argb(1, 255, 255, 255)); |
|
|
|
quoteToggle = (ImageButton) view.findViewById(R.id.toggle_quote_button); |
|
|
|
bodyFooterDivider = view.findViewById(R.id.body_footer_divider); |
|
|
|
postFooter = (LinearLayout) view.findViewById(R.id.post_footer); |
|
|
|
|
|
|
|
//User's extra info
|
|
|
|
header = (RelativeLayout) view.findViewById(R.id.header); |
|
|
|
userExtraInfo = (LinearLayout) view.findViewById(R.id.user_extra_info); |
|
|
|
specialRank = (TextView) view.findViewById(R.id.special_rank); |
|
|
|
rank = (TextView) view.findViewById(R.id.rank); |
|
|
|
gender = (TextView) view.findViewById(R.id.gender); |
|
|
|
numberOfPosts = (TextView) view.findViewById(R.id.number_of_posts); |
|
|
|
personalText = (TextView) view.findViewById(R.id.personal_text); |
|
|
|
stars = (TextView) view.findViewById(R.id.stars); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Custom {@link RecyclerView.ViewHolder} implementation |
|
|
|
*/ |
|
|
|
private static class QuickReplyViewHolder extends RecyclerView.ViewHolder { |
|
|
|
final EditText quickReply; |
|
|
|
final AppCompatImageButton submitButton; |
|
|
|
|
|
|
|
QuickReplyViewHolder(View quickReply) { |
|
|
|
super(quickReply); |
|
|
|
this.quickReply = (EditText) quickReply.findViewById(R.id.quick_reply_text); |
|
|
|
submitButton = (AppCompatImageButton) quickReply.findViewById(R.id.quick_reply_submit); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* This class is a gesture detector for WebViews. It handles post's clicks, long clicks and |
|
|
|
* touch and drag. |
|
|
@ -592,6 +647,7 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> { |
|
|
|
//Method always returns true as no url should be loaded in the WebViews
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|