From 083924964490f20c5d3871f4c80eca696b842fe4 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Sat, 9 Nov 2019 00:40:14 +0800 Subject: Compact post layout is available. Fixed WebView cannot be inflated on Android Lollipop. Tweak the comment item UI. --- .../infinityforreddit/Activity/LoginActivity.java | 3 +- .../infinityforreddit/Activity/MainActivity.java | 48 +- .../Adapter/CommentAndPostRecyclerViewAdapter.java | 8 +- .../Adapter/PostRecyclerViewAdapter.java | 1001 ++++++++++++++++---- .../CustomView/LollipopBugFixedWebView.java | 28 + .../infinityforreddit/Fragment/PostFragment.java | 24 +- .../Fragment/PostLayoutBottomSheetFragment.java | 65 ++ .../Fragment/PostTypeBottomSheetFragment.java | 58 +- .../infinityforreddit/FragmentCommunicator.java | 2 + .../infinityforreddit/SharedPreferencesUtils.java | 8 + app/src/main/res/layout/activity_login.xml | 2 +- .../layout/fragment_post_layot_bottom_sheet.xml | 47 + app/src/main/res/layout/item_comment.xml | 4 +- app/src/main/res/layout/item_post_compact.xml | 358 +++++++ app/src/main/res/menu/main_activity.xml | 6 + app/src/main/res/values/strings.xml | 5 +- 16 files changed, 1454 insertions(+), 213 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostLayoutBottomSheetFragment.java create mode 100644 app/src/main/res/layout/fragment_post_layot_bottom_sheet.xml create mode 100644 app/src/main/res/layout/item_post_compact.xml diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java index c5314d56..e081d5c6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java @@ -43,6 +43,8 @@ public class LoginActivity extends BaseActivity { @BindView(R.id.toolbar_login_activity) Toolbar toolbar; + @BindView(R.id.webview_login_activity) + WebView webView; @Inject @Named("no_oauth") Retrofit mRetrofit; @@ -68,7 +70,6 @@ public class LoginActivity extends BaseActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); - WebView webView = findViewById(R.id.webview_login_activity); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setDomStorageEnabled(true); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java index 823a8e2f..68edf1d1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java @@ -73,6 +73,7 @@ import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.FetchMyInfo; import ml.docilealligator.infinityforreddit.FetchSubscribedThing; import ml.docilealligator.infinityforreddit.Fragment.PostFragment; +import ml.docilealligator.infinityforreddit.Fragment.PostLayoutBottomSheetFragment; import ml.docilealligator.infinityforreddit.Fragment.PostTypeBottomSheetFragment; import ml.docilealligator.infinityforreddit.Fragment.SortTimeBottomSheetFragment; import ml.docilealligator.infinityforreddit.Fragment.SortTypeBottomSheetFragment; @@ -94,7 +95,7 @@ import pl.droidsonroids.gif.GifImageView; import retrofit2.Retrofit; public class MainActivity extends BaseActivity implements SortTypeSelectionCallback, - PostTypeBottomSheetFragment.PostTypeSelectionCallback { + PostTypeBottomSheetFragment.PostTypeSelectionCallback, PostLayoutBottomSheetFragment.PostLayoutSelectionCallback { static final String EXTRA_POST_TYPE = "EPT"; static final String EXTRA_MESSSAGE_FULLNAME = "ENF"; @@ -181,6 +182,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb private SortTypeBottomSheetFragment bestSortTypeBottomSheetFragment; private SortTypeBottomSheetFragment popularAndAllSortTypeBottomSheetFragment; private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; private boolean mNullAccessToken = false; private String mAccessToken; private String mAccountName; @@ -283,6 +285,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb popularAndAllSortTypeBottomSheetFragment.setArguments(popularBundle); sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); setSupportActionBar(toolbar); @@ -845,6 +848,8 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } } return true; + case R.id.action_change_post_layout_main_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); } return false; } @@ -917,6 +922,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } } + @Override + public void postLayoutSelected(int postLayout) { + sectionsPagerAdapter.changePostLayout(postLayout); + } + public void postScrollUp() { fab.show(); } @@ -1261,5 +1271,41 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb allPostFragment.changeNSFW(nsfw); } } + + void changePostLayout(int postLayout) { + if (mAccessToken == null) { + if (viewPager.getCurrentItem() == 0) { + if (popularPostFragment != null) { + mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST, postLayout).apply(); + ((FragmentCommunicator) popularPostFragment).changePostLayout(postLayout); + } + } else { + if (allPostFragment != null) { + mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_ALL_POST, postLayout).apply(); + ((FragmentCommunicator) allPostFragment).changePostLayout(postLayout); + } + } + } else { + switch (viewPager.getCurrentItem()) { + case 0: + if (frontPagePostFragment != null) { + mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, postLayout).apply(); + ((FragmentCommunicator) frontPagePostFragment).changePostLayout(postLayout); + } + break; + case 1: + if (popularPostFragment != null) { + mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST, postLayout).apply(); + ((FragmentCommunicator) popularPostFragment).changePostLayout(postLayout); + } + break; + case 2: + if (allPostFragment != null) { + mSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_ALL_POST, postLayout).apply(); + ((FragmentCommunicator) allPostFragment).changePostLayout(postLayout); + } + } + } + } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java index 50454381..cd7d0ad5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java @@ -606,7 +606,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter 0) { switch (comment.getDepth() % 7) { case 0: @@ -639,7 +639,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter 0) { switch (placeholder.getDepth() % 7) { case 0: @@ -978,7 +978,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter { + ((PostViewHolder) holder).cardView.setOnClickListener(view -> { if (canStartActivity) { canStartActivity = false; @@ -183,13 +191,13 @@ public class PostRecyclerViewAdapter extends PagedListAdapter= 0) { @@ -202,11 +210,11 @@ public class PostRecyclerViewAdapter extends PagedListAdapter= 0) { @@ -235,18 +243,18 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).nameTextView.setOnClickListener(view -> { if (canStartActivity) { canStartActivity = false; if (post.getSubredditNamePrefixed().startsWith("u/")) { @@ -263,8 +271,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter - ((DataViewHolder) holder).nameTextView.performClick()); + ((PostViewHolder) holder).iconGifImageView.setOnClickListener(view -> + ((PostViewHolder) holder).nameTextView.performClick()); } else { if (post.getAuthorIconUrl() == null) { String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditNamePrefixed().substring(2) : post.getAuthor(); @@ -273,13 +281,13 @@ public class PostRecyclerViewAdapter extends PagedListAdapter= 0) { @@ -292,17 +300,17 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).nameTextView.setOnClickListener(view -> { if (canStartActivity) { canStartActivity = false; Intent intent = new Intent(mContext, ViewUserDetailActivity.class); @@ -311,27 +319,27 @@ public class PostRecyclerViewAdapter extends PagedListAdapter - ((DataViewHolder) holder).nameTextView.performClick()); + ((PostViewHolder) holder).iconGifImageView.setOnClickListener(view -> + ((PostViewHolder) holder).nameTextView.performClick()); } - ((DataViewHolder) holder).postTimeTextView.setText(postTime); - ((DataViewHolder) holder).titleTextView.setText(title); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); + ((PostViewHolder) holder).postTimeTextView.setText(postTime); + ((PostViewHolder) holder).titleTextView.setText(title); + ((PostViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); if (gilded > 0) { - ((DataViewHolder) holder).gildedNumberTextView.setVisibility(View.VISIBLE); + ((PostViewHolder) holder).gildedNumberTextView.setVisibility(View.VISIBLE); String gildedNumber = mContext.getResources().getString(R.string.gilded_count, gilded); - ((DataViewHolder) holder).gildedNumberTextView.setText(gildedNumber); + ((PostViewHolder) holder).gildedNumberTextView.setText(gildedNumber); } if (post.isLocked()) { - ((DataViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); + ((PostViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); } if (nsfw) { if (!(mContext instanceof FilteredThingActivity)) { - ((DataViewHolder) holder).nsfwTextView.setOnClickListener(view -> { + ((PostViewHolder) holder).nsfwTextView.setOnClickListener(view -> { Intent intent = new Intent(mContext, FilteredThingActivity.class); intent.putExtra(FilteredThingActivity.EXTRA_NAME, post.getSubredditNamePrefixed().substring(2)); intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); @@ -339,68 +347,68 @@ public class PostRecyclerViewAdapter extends PagedListAdapter mCallback.typeChipClicked(post.getPostType())); + ((PostViewHolder) holder).typeTextView.setOnClickListener(view -> mCallback.typeChipClicked(post.getPostType())); } switch (post.getPostType()) { case Post.IMAGE_TYPE: - ((DataViewHolder) holder).typeTextView.setText(R.string.image); + ((PostViewHolder) holder).typeTextView.setText(R.string.image); final String imageUrl = post.getUrl(); - ((DataViewHolder) holder).imageView.setOnClickListener(view -> { + ((PostViewHolder) holder).imageView.setOnClickListener(view -> { Intent intent = new Intent(mContext, ViewImageActivity.class); intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, imageUrl); intent.putExtra(ViewImageActivity.FILE_NAME_KEY, subredditName @@ -409,13 +417,13 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).imageView.setOnClickListener(view -> { Intent intent = new Intent(mContext, LinkResolverActivity.class); Uri uri = Uri.parse(post.getUrl()); if (uri.getScheme() == null && uri.getHost() == null) { @@ -427,10 +435,10 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).imageView.setOnClickListener(view -> { Intent intent = new Intent(mContext, ViewGIFActivity.class); intent.setData(gifVideoUri); intent.putExtra(ViewGIFActivity.FILE_NAME_KEY, subredditName @@ -440,10 +448,10 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).imageView.setOnClickListener(view -> { Intent intent = new Intent(mContext, ViewVideoActivity.class); intent.setData(videoUri); intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName); @@ -452,14 +460,14 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).linkTextView.setText(noPreviewLinkDomain); + ((PostViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + ((PostViewHolder) holder).noPreviewLinkImageView.setOnClickListener(view -> { Intent intent = new Intent(mContext, LinkResolverActivity.class); Uri uri = Uri.parse(post.getUrl()); if (uri.getScheme() == null && uri.getHost() == null) { @@ -471,15 +479,15 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).upvoteButton.setOnClickListener(view -> { if (mAccessToken == null) { Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); return; @@ -490,48 +498,48 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).downvoteButton.setOnClickListener(view -> { if (mAccessToken == null) { Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); return; @@ -561,48 +569,48 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).saveButton.setOnClickListener(view -> { if (mAccessToken == null) { Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); return; } if (post.isSaved()) { - ((DataViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + ((PostViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, post.getFullName(), new SaveThing.SaveThingListener() { @Override public void success() { post.setSaved(false); - ((DataViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + ((PostViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); Toast.makeText(mContext, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); } @@ -650,19 +658,19 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + ((PostViewHolder) holder).shareButton.setOnClickListener(view -> { try { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); @@ -690,36 +698,584 @@ public class PostRecyclerViewAdapter extends PagedListAdapter() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); - ((DataViewHolder) holder).errorRelativeLayout.setVisibility(View.VISIBLE); - ((DataViewHolder) holder).errorRelativeLayout.setOnClickListener(view -> { - ((DataViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - ((DataViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); + ((PostCompactViewHolder) holder).itemView.setOnClickListener(view -> { + if (canStartActivity) { + canStartActivity = false; + + Intent intent = new Intent(mContext, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, post); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_LIST_POSITION, position); + mContext.startActivity(intent); + } + }); + + if (mDisplaySubredditName) { + if (authorPrefixed.equals(subredditNamePrefixed)) { + if (post.getAuthorIconUrl() == null) { + new LoadUserDataAsyncTask(mUserDao, post.getAuthor(), mRetrofit, iconImageUrl -> { + if (mContext != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getAuthorIconUrl().equals("")) { + mGlide.load(post.getAuthorIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } + } else { + if (post.getSubredditIconUrl() == null) { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, + iconImageUrl -> { + if (mContext != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setSubredditIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getSubredditIconUrl().equals("")) { + mGlide.load(post.getSubredditIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } + } + + ((PostCompactViewHolder) holder).nameTextView.setTextColor(mContext.getResources().getColor(R.color.colorAccent)); + ((PostCompactViewHolder) holder).nameTextView.setText(subredditNamePrefixed); + + ((PostCompactViewHolder) holder).nameTextView.setOnClickListener(view -> { + if (canStartActivity) { + canStartActivity = false; + if (post.getSubredditNamePrefixed().startsWith("u/")) { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, + post.getSubredditNamePrefixed().substring(2)); + mContext.startActivity(intent); + } else { + Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, + post.getSubredditNamePrefixed().substring(2)); + mContext.startActivity(intent); + } + } + }); + + ((PostCompactViewHolder) holder).iconGifImageView.setOnClickListener(view -> + ((PostCompactViewHolder) holder).nameTextView.performClick()); + } else { + if (post.getAuthorIconUrl() == null) { + String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditNamePrefixed().substring(2) : post.getAuthor(); + new LoadUserDataAsyncTask(mUserDao, authorName, mRetrofit, iconImageUrl -> { + if (mContext != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getAuthorIconUrl().equals("")) { + mGlide.load(post.getAuthorIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactViewHolder) holder).iconGifImageView); + } + + ((PostCompactViewHolder) holder).nameTextView.setTextColor(mContext.getResources().getColor(R.color.colorPrimaryDarkDayNightTheme)); + ((PostCompactViewHolder) holder).nameTextView.setText(authorPrefixed); + + ((PostCompactViewHolder) holder).nameTextView.setOnClickListener(view -> { + if (canStartActivity) { + canStartActivity = false; + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); + mContext.startActivity(intent); + } + }); + + ((PostCompactViewHolder) holder).iconGifImageView.setOnClickListener(view -> + ((PostCompactViewHolder) holder).nameTextView.performClick()); + } + + ((PostCompactViewHolder) holder).postTimeTextView.setText(postTime); + ((PostCompactViewHolder) holder).titleTextView.setText(title); + ((PostCompactViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); + + if (gilded > 0) { + ((PostCompactViewHolder) holder).gildedNumberTextView.setVisibility(View.VISIBLE); + String gildedNumber = mContext.getResources().getString(R.string.gilded_count, gilded); + ((PostCompactViewHolder) holder).gildedNumberTextView.setText(gildedNumber); + } + + if (post.isLocked()) { + ((PostCompactViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); + } + + if (nsfw) { + if (!(mContext instanceof FilteredThingActivity)) { + ((PostCompactViewHolder) holder).nsfwTextView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, post.getSubredditNamePrefixed().substring(2)); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, Post.NSFW_TYPE); + mContext.startActivity(intent); + }); + } + ((PostCompactViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); + } + + if (spoiler) { + ((PostCompactViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE); + } + + if (flair != null) { + ((PostCompactViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); + ((PostCompactViewHolder) holder).flairTextView.setText(flair); + } + + switch (voteType) { + case 1: + //Upvoted + ((PostCompactViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.upvoted), android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.upvoted)); + break; + case -1: + //Downvoted + ((PostCompactViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.downvoted), android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.downvoted)); + break; + } + + if (post.getPostType() != Post.TEXT_TYPE && post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { + ((PostCompactViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); + ((PostCompactViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostCompactViewHolder) holder).imageView.setVisibility(View.VISIBLE); loadImage(holder, post); + } + + if (mPostType == PostDataSource.TYPE_SUBREDDIT && !mDisplaySubredditName && post.isStickied()) { + ((PostCompactViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostCompactViewHolder) holder).stickiedPostImageView); + } + + if (isArchived) { + ((PostCompactViewHolder) holder).archivedImageView.setVisibility(View.VISIBLE); + + ((PostCompactViewHolder) holder).upvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.voteAndReplyUnavailableVoteButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactViewHolder) holder).downvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.voteAndReplyUnavailableVoteButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (post.isCrosspost()) { + ((PostCompactViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); + } + + if (!(mContext instanceof FilteredThingActivity)) { + ((PostCompactViewHolder) holder).typeTextView.setOnClickListener(view -> mCallback.typeChipClicked(post.getPostType())); + } + + switch (post.getPostType()) { + case Post.IMAGE_TYPE: + ((PostCompactViewHolder) holder).typeTextView.setText(R.string.image); + + final String imageUrl = post.getUrl(); + ((PostCompactViewHolder) holder).imageView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewImageActivity.class); + intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, imageUrl); + intent.putExtra(ViewImageActivity.FILE_NAME_KEY, subredditName + + "-" + id + ".jpg"); + mContext.startActivity(intent); + }); + break; + case Post.LINK_TYPE: + ((PostCompactViewHolder) holder).typeTextView.setText(R.string.link); + + ((PostCompactViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); + String domain = Uri.parse(post.getUrl()).getHost(); + ((PostCompactViewHolder) holder).linkTextView.setText(domain); + + ((PostCompactViewHolder) holder).imageView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, LinkResolverActivity.class); + Uri uri = Uri.parse(post.getUrl()); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(post.getUrl())); + } else { + intent.setData(uri); + } + mContext.startActivity(intent); + }); + break; + case Post.GIF_TYPE: + ((PostCompactViewHolder) holder).typeTextView.setText(R.string.gif); + + final Uri gifVideoUri = Uri.parse(post.getVideoUrl()); + ((PostCompactViewHolder) holder).imageView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewGIFActivity.class); + intent.setData(gifVideoUri); + intent.putExtra(ViewGIFActivity.FILE_NAME_KEY, subredditName + + "-" + id + ".gif"); + intent.putExtra(ViewGIFActivity.IMAGE_URL_KEY, post.getVideoUrl()); + mContext.startActivity(intent); + }); + break; + case Post.VIDEO_TYPE: + ((PostCompactViewHolder) holder).typeTextView.setText(R.string.video); + + final Uri videoUri = Uri.parse(post.getVideoUrl()); + ((PostCompactViewHolder) holder).imageView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewVideoActivity.class); + intent.setData(videoUri); + intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName); + intent.putExtra(ViewVideoActivity.ID_KEY, fullName); + mContext.startActivity(intent); + }); + break; + case Post.NO_PREVIEW_LINK_TYPE: + ((PostCompactViewHolder) holder).typeTextView.setText(R.string.link); + + String noPreviewLinkUrl = post.getUrl(); + ((PostCompactViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); + String noPreviewLinkDomain = Uri.parse(noPreviewLinkUrl).getHost(); + ((PostCompactViewHolder) holder).linkTextView.setText(noPreviewLinkDomain); + ((PostCompactViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + ((PostCompactViewHolder) holder).noPreviewLinkImageView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, LinkResolverActivity.class); + Uri uri = Uri.parse(post.getUrl()); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(post.getUrl())); + } else { + intent.setData(uri); + } + mContext.startActivity(intent); + }); + break; + case Post.TEXT_TYPE: + ((PostCompactViewHolder) holder).typeTextView.setText(R.string.text); + break; + } + + ((PostCompactViewHolder) holder).upvoteButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (isArchived) { + Toast.makeText(mContext, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = ((PostCompactViewHolder) holder).upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = ((PostCompactViewHolder) holder).downvoteButton.getColorFilter(); + int previousScoreTextViewColor = ((PostCompactViewHolder) holder).scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + ((PostCompactViewHolder) holder).downvoteButton.clearColorFilter(); + + if (previousUpvoteButtonColorFilter == null) { + //Not upvoted before + post.setVoteType(1); + newVoteType = RedditUtils.DIR_UPVOTE; + ((PostCompactViewHolder) holder).upvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.upvoted), android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.upvoted)); + } else { + //Upvoted before + post.setVoteType(0); + newVoteType = RedditUtils.DIR_UNVOTE; + ((PostCompactViewHolder) holder).upvoteButton.clearColorFilter(); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.defaultTextColor)); + } + + ((PostCompactViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); + + VoteThing.voteThing(mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(RedditUtils.DIR_UPVOTE)) { + post.setVoteType(1); + ((PostCompactViewHolder) holder).upvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.upvoted), android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.upvoted)); + } else { + post.setVoteType(0); + ((PostCompactViewHolder) holder).upvoteButton.clearColorFilter(); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.defaultTextColor)); + } + + ((PostCompactViewHolder) holder).downvoteButton.clearColorFilter(); + ((PostCompactViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mContext, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + ((PostCompactViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + previousVoteType)); + ((PostCompactViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + ((PostCompactViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(previousScoreTextViewColor); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }, fullName, newVoteType, holder.getAdapterPosition()); + }); + + ((PostCompactViewHolder) holder).downvoteButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (isArchived) { + Toast.makeText(mContext, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = ((PostCompactViewHolder) holder).upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = ((PostCompactViewHolder) holder).downvoteButton.getColorFilter(); + int previousScoreTextViewColor = ((PostCompactViewHolder) holder).scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + ((PostCompactViewHolder) holder).upvoteButton.clearColorFilter(); + + if (previousDownvoteButtonColorFilter == null) { + //Not downvoted before + post.setVoteType(-1); + newVoteType = RedditUtils.DIR_DOWNVOTE; + ((PostCompactViewHolder) holder).downvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.downvoted), android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.downvoted)); + } else { + //Downvoted before + post.setVoteType(0); + newVoteType = RedditUtils.DIR_UNVOTE; + ((PostCompactViewHolder) holder).downvoteButton.clearColorFilter(); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.defaultTextColor)); + } + + ((PostCompactViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); + + VoteThing.voteThing(mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) { + post.setVoteType(-1); + ((PostCompactViewHolder) holder).downvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.downvoted), android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.downvoted)); + } else { + post.setVoteType(0); + ((PostCompactViewHolder) holder).downvoteButton.clearColorFilter(); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(ContextCompat.getColor(mContext, R.color.defaultTextColor)); + } + + ((PostCompactViewHolder) holder).upvoteButton.clearColorFilter(); + ((PostCompactViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mContext, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + ((PostCompactViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + previousVoteType)); + ((PostCompactViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + ((PostCompactViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + ((PostCompactViewHolder) holder).scoreTextView.setTextColor(previousScoreTextViewColor); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }, fullName, newVoteType, holder.getAdapterPosition()); + }); + + ((PostCompactViewHolder) holder).commentsCountTextView.setText(Integer.toString(post.getNComments())); + + if (post.isSaved()) { + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + + ((PostCompactViewHolder) holder).saveButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (post.isSaved()) { + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(false); + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mContext, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void failed() { + post.setSaved(true); + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mContext, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }); + } else { + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(true); + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mContext, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void failed() { + post.setSaved(false); + ((PostCompactViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mContext, R.string.post_saved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }); + } }); - return false; - } - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((DataViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); - ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; + ((PostCompactViewHolder) holder).shareButton.setOnClickListener(view -> { + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + String extraText = title + "\n" + permalink; + intent.putExtra(Intent.EXTRA_TEXT, extraText); + mContext.startActivity(Intent.createChooser(intent, mContext.getString(R.string.share))); + } catch (ActivityNotFoundException e) { + Toast.makeText(mContext, R.string.no_activity_found_for_share, Toast.LENGTH_SHORT).show(); + } + }); } - }); + } + } - if ((post.isNSFW() && mNeedBlurNSFW) || post.isSpoiler() && mNeedBlurSpoiler) { - imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 2))) - .into(((DataViewHolder) holder).imageView); - } else { - imageRequestBuilder.into(((DataViewHolder) holder).imageView); + private void loadImage(final RecyclerView.ViewHolder holder, final Post post) { + if (holder instanceof PostViewHolder) { + RequestBuilder imageRequestBuilder = mGlide.load(post.getPreviewUrl()).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + ((PostViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostViewHolder) holder).errorRelativeLayout.setVisibility(View.VISIBLE); + ((PostViewHolder) holder).errorRelativeLayout.setOnClickListener(view -> { + ((PostViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); + loadImage(holder, post); + }); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((PostViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); + ((PostViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + }); + + if ((post.isNSFW() && mNeedBlurNSFW) || post.isSpoiler() && mNeedBlurSpoiler) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 2))) + .into(((PostViewHolder) holder).imageView); + } else { + imageRequestBuilder.into(((PostViewHolder) holder).imageView); + } + } else if (holder instanceof PostCompactViewHolder) { + RequestBuilder imageRequestBuilder = mGlide.load(post.getPreviewUrl()).error(R.drawable.ic_error_outline_black_24dp); + if ((post.isNSFW() && mNeedBlurNSFW) || post.isSpoiler() && mNeedBlurSpoiler) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 2))) + .into(((PostCompactViewHolder) holder).imageView); + } else { + imageRequestBuilder.into(((PostCompactViewHolder) holder).imageView); + } } } @@ -749,6 +1305,10 @@ public class PostRecyclerViewAdapter extends PagedListAdapter { + //Do nothing in order to prevent clicking this to start ViewPostDetailActivity + }); + + if (mVoteButtonsOnTheRight) { + ConstraintSet constraintSet = new ConstraintSet(); + constraintSet.clone(bottomConstraintLayout); + constraintSet.clear(upvoteButton.getId(), ConstraintSet.START); + constraintSet.clear(scoreTextView.getId(), ConstraintSet.START); + constraintSet.clear(downvoteButton.getId(), ConstraintSet.START); + constraintSet.clear(saveButton.getId(), ConstraintSet.END); + constraintSet.clear(shareButton.getId(), ConstraintSet.END); + constraintSet.connect(upvoteButton.getId(), ConstraintSet.END, scoreTextView.getId(), ConstraintSet.START); + constraintSet.connect(scoreTextView.getId(), ConstraintSet.END, downvoteButton.getId(), ConstraintSet.START); + constraintSet.connect(downvoteButton.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END); + constraintSet.connect(commentsCountTextView.getId(), ConstraintSet.START, saveButton.getId(), ConstraintSet.END); + constraintSet.connect(commentsCountTextView.getId(), ConstraintSet.END, upvoteButton.getId(), ConstraintSet.START); + constraintSet.connect(saveButton.getId(), ConstraintSet.START, shareButton.getId(), ConstraintSet.END); + constraintSet.connect(shareButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); + constraintSet.setHorizontalBias(commentsCountTextView.getId(), 0); + constraintSet.applyTo(bottomConstraintLayout); + } + } + } + + class PostCompactViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_compact) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.name_text_view_item_post_compact) + TextView nameTextView; + @BindView(R.id.stickied_post_image_view_item_post_compact) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_best_item_post_compact) + TextView postTimeTextView; + @BindView(R.id.title_text_view_best_item_post_compact) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_compact) + CustomTextView typeTextView; + @BindView(R.id.gilded_number_text_view_item_post_compact) + TextView gildedNumberTextView; + @BindView(R.id.archived_image_view_item_post_compact) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_compact) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_compact) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_compact) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_compact) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_compact) + CustomTextView flairTextView; + @BindView(R.id.link_text_view_item_post_compact) + TextView linkTextView; + @BindView(R.id.image_view_wrapper_item_post_compact) + RelativeLayout relativeLayout; + @BindView(R.id.progress_bar_item_post_compact) + ProgressBar progressBar; + @BindView(R.id.image_view_best_post_item) + ImageView imageView; + @BindView(R.id.image_view_no_preview_link_item_post_compact) + ImageView noPreviewLinkImageView; + @BindView(R.id.bottom_constraint_layout_item_post_compact) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_compact) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_compact) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_compact) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_compact) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_compact) + ImageView saveButton; + @BindView(R.id.share_button_item_post_compact) + ImageView shareButton; + + PostCompactViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); scoreTextView.setOnClickListener(view -> { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java new file mode 100644 index 00000000..286aaf4c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java @@ -0,0 +1,28 @@ +package ml.docilealligator.infinityforreddit.CustomView; + +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.util.AttributeSet; +import android.webkit.WebView; + +public class LollipopBugFixedWebView extends WebView{ + public LollipopBugFixedWebView(Context context) { + super(getFixedContext(context)); + } + + public LollipopBugFixedWebView(Context context, AttributeSet attrs) { + super(getFixedContext(context), attrs); + } + + public LollipopBugFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) { + super(getFixedContext(context), attrs, defStyleAttr); + } + + // To fix Android Lollipop WebView problem create a new configuration on that Android version only + private static Context getFixedContext(Context context) { + if (Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22) // Android Lollipop 5.0 & 5.1 + return context.createConfigurationContext(new Configuration()); + return context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java index 921763c6..5651ac0b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java @@ -28,6 +28,7 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.paging.PagedList; +import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.RecyclerView; @@ -118,6 +119,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { private LazyModeRunnable lazyModeRunnable; private CountDownTimer resumeLazyModeCountDownTimer; private float lazyModeInterval; + private int postLayout; public PostFragment() { // Required empty public constructor @@ -287,9 +289,10 @@ public class PostFragment extends Fragment implements FragmentCommunicator { String sort = mSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SEARCH_POST, SortType.Type.RELEVANCE.name()); String sortTime = mSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_SEARCH_POST, SortType.Time.ALL.name()); SortType sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); + postLayout = mSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST, SharedPreferencesUtils.POST_LAYOUT_CARD); mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase, - accessToken, postType, true, needBlurNsfw, needBlurSpoiler, + accessToken, postType, postLayout, true, needBlurNsfw, needBlurSpoiler, voteButtonsOnTheRight, new PostRecyclerViewAdapter.Callback() { @Override public void retryLoadingMore() { @@ -329,17 +332,20 @@ public class PostFragment extends Fragment implements FragmentCommunicator { if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { sortTime = mSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_POPULAR_POST, SortType.Time.ALL.name()); } + postLayout = mSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST, SharedPreferencesUtils.POST_LAYOUT_CARD); } else { sort = mSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_ALL_POST, SortType.Type.HOT.name()); if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { sortTime = mSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_ALL_POST, SortType.Time.ALL.name()); } + postLayout = mSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_ALL_POST, SharedPreferencesUtils.POST_LAYOUT_CARD); } } else { sort = mSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SUBREDDIT_POST, SortType.Type.HOT.name()); if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { sortTime = mSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_SUBREDDIT_POST, SortType.Time.ALL.name()); } + postLayout = mSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST, SharedPreferencesUtils.POST_LAYOUT_CARD); } if(sortTime != null) { @@ -349,7 +355,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase, - accessToken, postType, displaySubredditName, needBlurNsfw, needBlurSpoiler, + accessToken, postType, postLayout, displaySubredditName, needBlurNsfw, needBlurSpoiler, voteButtonsOnTheRight, new PostRecyclerViewAdapter.Callback() { @Override public void retryLoadingMore() { @@ -392,9 +398,10 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } else { sortType = new SortType(SortType.Type.valueOf(sort)); } + postLayout = mSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST, SharedPreferencesUtils.POST_LAYOUT_CARD); mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase, - accessToken, postType, true, needBlurNsfw, needBlurSpoiler, + accessToken, postType, postLayout, true, needBlurNsfw, needBlurSpoiler, voteButtonsOnTheRight, new PostRecyclerViewAdapter.Callback() { @Override public void retryLoadingMore() { @@ -430,9 +437,10 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } else { sortType = new SortType(SortType.Type.valueOf(sort)); } + postLayout = mSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, SharedPreferencesUtils.POST_LAYOUT_CARD); mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase, - accessToken, postType, true, needBlurNsfw, needBlurSpoiler, + accessToken, postType, postLayout, true, needBlurNsfw, needBlurSpoiler, voteButtonsOnTheRight, new PostRecyclerViewAdapter.Callback() { @Override public void retryLoadingMore() { @@ -608,6 +616,14 @@ public class PostFragment extends Fragment implements FragmentCommunicator { return isInLazyMode; } + @Override + public void changePostLayout(int postLayout) { + if (mAdapter != null) { + mAdapter.setPostLayout(postLayout); + refreshAdapter(); + } + } + @Subscribe public void onPostUpdateEvent(PostUpdateEventToPostList event) { PagedList posts = mAdapter.getCurrentList(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostLayoutBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostLayoutBottomSheetFragment.java new file mode 100644 index 00000000..f4bcce9c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostLayoutBottomSheetFragment.java @@ -0,0 +1,65 @@ +package ml.docilealligator.infinityforreddit.Fragment; + + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SharedPreferencesUtils; + +/** + * A simple {@link Fragment} subclass. + */ +public class PostLayoutBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + @BindView(R.id.card_layout_text_view_post_layout_bottom_sheet_fragment) + TextView cardLayoutTextView; + @BindView(R.id.compact_layout_text_view_post_layout_bottom_sheet_fragment) + TextView compactLayoutTextView; + private Activity activity; + public PostLayoutBottomSheetFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_post_layot_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + cardLayoutTextView.setOnClickListener(view -> { + ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_CARD); + dismiss(); + }); + compactLayoutTextView.setOnClickListener(view -> { + ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_COMPACT); + dismiss(); + }); + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } + + public interface PostLayoutSelectionCallback { + void postLayoutSelected(int postLayout); + } + +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostTypeBottomSheetFragment.java index 7ca85e35..853cee6a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostTypeBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostTypeBottomSheetFragment.java @@ -2,6 +2,7 @@ package ml.docilealligator.infinityforreddit.Fragment; import android.app.Activity; +import android.content.Context; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; @@ -10,6 +11,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; @@ -36,6 +38,7 @@ public class PostTypeBottomSheetFragment extends RoundedBottomSheetDialogFragmen LinearLayout imageTypeLinearLayout; @BindView(R.id.video_type_linear_layout_post_type_bottom_sheet_fragment) LinearLayout videoTypeLinearLayout; + private Activity activity; public PostTypeBottomSheetFragment() { // Required empty public constructor } @@ -46,38 +49,39 @@ public class PostTypeBottomSheetFragment extends RoundedBottomSheetDialogFragmen View rootView = inflater.inflate(R.layout.fragment_post_type_bottom_sheet, container, false); ButterKnife.bind(this, rootView); - Activity activity = getActivity(); - - if (activity != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - textTypeLinearLayout.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_TEXT); - dismiss(); - }); - - linkTypeLinearLayout.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_LINK); - dismiss(); - }); - - imageTypeLinearLayout.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_IMAGE); - dismiss(); - }); - - videoTypeLinearLayout.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_VIDEO); - dismiss(); - }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); } + textTypeLinearLayout.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_TEXT); + dismiss(); + }); + + linkTypeLinearLayout.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_LINK); + dismiss(); + }); + + imageTypeLinearLayout.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_IMAGE); + dismiss(); + }); + + videoTypeLinearLayout.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_VIDEO); + dismiss(); + }); + return rootView; } + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } public interface PostTypeSelectionCallback { void postTypeSelected(int postType); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java index 520abb9b..5d66dc49 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java @@ -23,4 +23,6 @@ public interface FragmentCommunicator { return false; } + default void changePostLayout(int postLayout) { } + } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SharedPreferencesUtils.java index b11f4c32..1fd5c9f9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SharedPreferencesUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SharedPreferencesUtils.java @@ -47,4 +47,12 @@ public class SharedPreferencesUtils { public static final String SORT_TYPE_SEARCH_SUBREDDIT = "sort_type_search_subreddit"; public static final String SORT_TYPE_SEARCH_USER = "sort_type_search_user"; public static final String SORT_TYPE_POST_COMMENT = "sort_type_post_comment"; + public static final String POST_LAYOUT_FRONT_PAGE_POST = "post_layout_best_post"; + public static final String POST_LAYOUT_POPULAR_POST = "post_layout_popular_post"; + public static final String POST_LAYOUT_ALL_POST = "post_layout_all_post"; + public static final String POST_LAYOUT_SUBREDDIT_POST = "post_layout_subreddit_post"; + public static final String POST_LAYOUT_USER_POST = "post_layout_user_post"; + public static final String POST_LAYOUT_SEARCH_POST = "post_layout_search_post"; + public static final int POST_LAYOUT_CARD = 0; + public static final int POST_LAYOUT_COMPACT = 1; } diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 904d3ab2..2145e703 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -22,7 +22,7 @@ - + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_comment.xml b/app/src/main/res/layout/item_comment.xml index ae22e5e5..ee85314e 100644 --- a/app/src/main/res/layout/item_comment.xml +++ b/app/src/main/res/layout/item_comment.xml @@ -89,8 +89,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" - android:layout_marginStart="32dp" - android:layout_marginEnd="32dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" android:layout_marginBottom="8dp" android:textColor="@color/primaryTextColor" android:textSize="?attr/content_font_default" /> diff --git a/app/src/main/res/layout/item_post_compact.xml b/app/src/main/res/layout/item_post_compact.xml new file mode 100644 index 00000000..cdf3bd64 --- /dev/null +++ b/app/src/main/res/layout/item_post_compact.xml @@ -0,0 +1,358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/main_activity.xml b/app/src/main/res/menu/main_activity.xml index 1ae1fadb..cfc38eff 100644 --- a/app/src/main/res/menu/main_activity.xml +++ b/app/src/main/res/menu/main_activity.xml @@ -36,4 +36,10 @@ android:orderInCategory="5" android:title="@string/action_start_lazy_mode" app:showAsAction="never" /> + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d8dc8b01..dd113044 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,6 +41,7 @@ Mark Spoiler Unmark Spoiler Edit Flair + Change Post Layout Error occurred when parsing the JSON response Error Retrieving the token @@ -349,6 +350,6 @@ Favorites All - - Hello blank fragment + Card Layout + Compact Layout -- cgit v1.2.3