diff options
Diffstat (limited to 'app')
19 files changed, 6109 insertions, 18 deletions
diff --git a/app/build.gradle b/app/build.gradle index e278f7dd..cb069dc1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,11 +46,11 @@ android { dependencies { /** AndroidX **/ - implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.biometric:biometric:1.2.0-alpha04' implementation 'androidx.browser:browser:1.4.0' implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.2' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.legacy:legacy-support-v4:1.0.0' def lifecycleVersion = "2.3.1" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" @@ -61,11 +61,12 @@ dependencies { def pagingVersion = '3.1.0' implementation "androidx.paging:paging-runtime:$pagingVersion" implementation "androidx.paging:paging-guava:$pagingVersion" - implementation 'androidx.preference:preference:1.1.1' + implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.recyclerview:recyclerview:1.2.1' def roomVersion = "2.4.2" implementation "androidx.room:room-runtime:$roomVersion" annotationProcessor "androidx.room:room-compiler:$roomVersion" + implementation "androidx.room:room-guava:$roomVersion" implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01' implementation 'androidx.work:work-runtime:2.7.1' implementation 'com.google.android.material:material:1.5.0-alpha05' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d343bfe6..202ceb42 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -35,6 +35,12 @@ android:usesCleartextTraffic="true" tools:replace="android:label"> <activity + android:name=".activities.HistoryActivity" + android:exported="false" + android:label="@string/history_activity_label" + android:parentActivityName=".activities.MainActivity" + android:theme="@style/AppTheme.Slidable" /> + <activity android:name=".activities.PostPollActivity" android:label="@string/post_poll_activity_label" android:parentActivityName=".activities.MainActivity" @@ -73,10 +79,10 @@ android:theme="@style/AppTheme.NoActionBar" /> <activity android:name=".activities.WebViewActivity" + android:configChanges="orientation|screenSize" android:label="" android:parentActivityName=".activities.MainActivity" - android:theme="@style/AppTheme.NoActionBar" - android:configChanges="orientation|screenSize" /> + android:theme="@style/AppTheme.NoActionBar" /> <activity android:name=".activities.SuicidePreventionActivity" android:parentActivityName=".activities.MainActivity" @@ -215,24 +221,21 @@ <activity android:name=".activities.ShareDataResolverActivity" android:exported="true"> - <intent-filter - android:label="@string/submit_post"> + <intent-filter android:label="@string/submit_post"> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> - <intent-filter - android:label="@string/submit_post"> + <intent-filter android:label="@string/submit_post"> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="video/*" /> </intent-filter> - <intent-filter - android:label="@string/submit_post"> + <intent-filter android:label="@string/submit_post"> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> @@ -278,8 +281,7 @@ <activity android:name=".activities.LinkResolverActivity" android:exported="true"> - <intent-filter - android:label="@string/handle_link"> + <intent-filter android:label="@string/handle_link"> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index 6b899a13..79b2961b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -19,6 +19,7 @@ import ml.docilealligator.infinityforreddit.activities.FetchRandomSubredditOrPos import ml.docilealligator.infinityforreddit.activities.FilteredPostsActivity; import ml.docilealligator.infinityforreddit.activities.FullMarkdownActivity; import ml.docilealligator.infinityforreddit.activities.GiveAwardActivity; +import ml.docilealligator.infinityforreddit.activities.HistoryActivity; import ml.docilealligator.infinityforreddit.activities.InboxActivity; import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; import ml.docilealligator.infinityforreddit.activities.LockScreenActivity; @@ -65,6 +66,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.AccountChooserB import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; import ml.docilealligator.infinityforreddit.fragments.FollowedUsersListingFragment; +import ml.docilealligator.infinityforreddit.fragments.HistoryPostFragment; import ml.docilealligator.infinityforreddit.fragments.InboxFragment; import ml.docilealligator.infinityforreddit.fragments.MultiRedditListingFragment; import ml.docilealligator.infinityforreddit.fragments.PostFragment; @@ -300,4 +302,8 @@ public interface AppComponent { void inject(AccountChooserBottomSheetFragment accountChooserBottomSheetFragment); void inject(MaterialYouWorker materialYouWorker); + + void inject(HistoryPostFragment historyPostFragment); + + void inject(HistoryActivity historyActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java index 229e047c..29964dac 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java @@ -1,6 +1,7 @@ package ml.docilealligator.infinityforreddit; import android.content.Context; +import android.database.Cursor; import android.graphics.Color; import androidx.annotation.NonNull; @@ -37,7 +38,7 @@ import ml.docilealligator.infinityforreddit.user.UserData; @Database(entities = {Account.class, SubredditData.class, SubscribedSubredditData.class, UserData.class, SubscribedUserData.class, MultiReddit.class, CustomTheme.class, RecentSearchQuery.class, - ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class}, version = 22) + ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class}, version = 23) public abstract class RedditDataRoomDatabase extends RoomDatabase { private static RedditDataRoomDatabase INSTANCE; @@ -52,7 +53,7 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13, MIGRATION_13_14, MIGRATION_14_15, MIGRATION_15_16, MIGRATION_16_17, MIGRATION_17_18, MIGRATION_18_19, MIGRATION_19_20, MIGRATION_20_21, - MIGRATION_21_22) + MIGRATION_21_22, MIGRATION_22_23) .build(); } } @@ -365,4 +366,29 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { database.execSQL("ALTER TABLE users ADD COLUMN title TEXT"); } }; + private static final Migration MIGRATION_22_23 = new Migration(22, 23) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("ALTER TABLE read_posts ADD COLUMN time INTEGER DEFAULT 0 NOT NULL"); + Cursor cursor = database.query("SELECT * FROM read_posts"); + int row = 0; + database.beginTransaction(); + try { + while (cursor.moveToNext()) { + int index; + + index = cursor.getColumnIndexOrThrow("username"); + String username = cursor.getString(index); + + index = cursor.getColumnIndexOrThrow("id"); + String id = cursor.getString(index); + + database.execSQL("UPDATE read_posts SET time = " + row++ + " WHERE username = '" + username + "' AND id = '" + id + "'"); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + } + }; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/HistoryActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/HistoryActivity.java new file mode 100644 index 00000000..19a0849b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/HistoryActivity.java @@ -0,0 +1,334 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.tabs.TabLayout; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; +import ml.docilealligator.infinityforreddit.fragments.HistoryPostFragment; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class HistoryActivity extends BaseActivity implements ActivityToolbarInterface, + PostLayoutBottomSheetFragment.PostLayoutSelectionCallback { + + @BindView(R.id.coordinator_layout_history_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_history_activity) + AppBarLayout appBarLayout; + @BindView(R.id.collapsing_toolbar_layout_history_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.toolbar_history_activity) + Toolbar toolbar; + @BindView(R.id.tab_layout_tab_layout_history_activity_activity) + TabLayout tabLayout; + @BindView(R.id.view_pager_history_activity) + ViewPager2 viewPager2; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences mCurrentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private FragmentManager fragmentManager; + private SectionsPagerAdapter sectionsPagerAdapter; + private SlidrInterface mSlidrInterface; + private String mAccessToken; + private String mAccountName; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_history); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.setDecorFitsSystemWindows(false); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + fragmentManager = getSupportFragmentManager(); + + mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); + mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); + + initializeViewPager(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (sectionsPagerAdapter != null) { + return sectionsPagerAdapter.handleKeyDown(keyCode) || super.onKeyDown(keyCode, event); + } + + return super.onKeyDown(keyCode, event); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); + applyTabLayoutTheme(tabLayout); + } + + private void initializeViewPager() { + sectionsPagerAdapter = new SectionsPagerAdapter(this); + tabLayout.setVisibility(View.GONE); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(2); + //viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); + viewPager2.setUserInputEnabled(false); + /*new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { + switch (position) { + case 0: + Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.posts)); + break; + } + }).attach();*/ + + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + if (position == 0) { + unlockSwipeRightToGoBack(); + } else { + lockSwipeRightToGoBack(); + } + } + }); + + fixViewPager2Sensitivity(viewPager2); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.history_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + finish(); + return true; + } else if (itemId == R.id.action_refresh_history_activity) { + sectionsPagerAdapter.refresh(); + return true; + } else if (itemId == R.id.action_change_post_layout_history_activity) { + PostLayoutBottomSheetFragment postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + } + return false; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { + sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); + } + + @Override + public void onLongPress() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.goBackToTop(); + } + } + + public void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + public void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + + @Override + public void postLayoutSelected(int postLayout) { + if (sectionsPagerAdapter != null) { + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + mAccountName, postLayout).apply(); + sectionsPagerAdapter.changePostLayout(postLayout); + } + } + + private class SectionsPagerAdapter extends FragmentStateAdapter { + + SectionsPagerAdapter(FragmentActivity fa) { + super(fa); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + if (position == 0) { + HistoryPostFragment fragment = new HistoryPostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(HistoryPostFragment.EXTRA_HISTORY_TYPE, HistoryPostFragment.HISTORY_TYPE_READ_POSTS); + bundle.putString(HistoryPostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(HistoryPostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } else { + HistoryPostFragment fragment = new HistoryPostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(HistoryPostFragment.EXTRA_HISTORY_TYPE, HistoryPostFragment.HISTORY_TYPE_READ_POSTS); + bundle.putString(HistoryPostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(HistoryPostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + } + + @Nullable + private Fragment getCurrentFragment() { + if (viewPager2 == null || fragmentManager == null) { + return null; + } + return fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); + } + + public boolean handleKeyDown(int keyCode) { + if (viewPager2.getCurrentItem() == 0) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + return ((PostFragment) fragment).handleKeyDown(keyCode); + } + } + return false; + } + + public void refresh() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).refresh(); + } else if (fragment instanceof CommentsListingFragment) { + ((CommentsListingFragment) fragment).refresh(); + } + } + + public void changeNSFW(boolean nsfw) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeNSFW(nsfw); + } + } + + public void changePostLayout(int postLayout) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changePostLayout(postLayout); + } + } + + + public void goBackToTop() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).goBackToTop(); + } else if (fragment instanceof CommentsListingFragment) { + ((CommentsListingFragment) fragment).goBackToTop(); + } + } + + @Override + public int getItemCount() { + return 1; + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java index 89c139bf..31d7dd33 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java @@ -733,11 +733,13 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } }); navigationWrapper.floatingActionButton.setOnLongClickListener(view -> { - FABMoreOptionsBottomSheetFragment fabMoreOptionsBottomSheetFragment= new FABMoreOptionsBottomSheetFragment(); + /*FABMoreOptionsBottomSheetFragment fabMoreOptionsBottomSheetFragment= new FABMoreOptionsBottomSheetFragment(); Bundle bundle = new Bundle(); bundle.putBoolean(FABMoreOptionsBottomSheetFragment.EXTRA_ANONYMOUS_MODE, mAccessToken == null); fabMoreOptionsBottomSheetFragment.setArguments(bundle); - fabMoreOptionsBottomSheetFragment.show(getSupportFragmentManager(), fabMoreOptionsBottomSheetFragment.getTag()); + fabMoreOptionsBottomSheetFragment.show(getSupportFragmentManager(), fabMoreOptionsBottomSheetFragment.getTag());*/ + Intent intent = new Intent(this, HistoryActivity.class); + startActivity(intent); return true; }); navigationWrapper.floatingActionButton.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/HistoryPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/HistoryPostRecyclerViewAdapter.java new file mode 100644 index 00000000..201e7930 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/HistoryPostRecyclerViewAdapter.java @@ -0,0 +1,4310 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.ColorFilter; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.Barrier; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.constraintlayout.widget.ConstraintSet; +import androidx.core.content.ContextCompat; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.paging.PagingDataAdapter; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestBuilder; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.Target; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; +import com.google.android.exoplayer2.ui.PlayerView; +import com.libRG.CustomTextView; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.Locale; +import java.util.concurrent.Executor; + +import butterknife.BindView; +import butterknife.ButterKnife; +import im.ene.toro.CacheManager; +import im.ene.toro.ToroPlayer; +import im.ene.toro.ToroUtil; +import im.ene.toro.exoplayer.ExoCreator; +import im.ene.toro.exoplayer.ExoPlayerViewHelper; +import im.ene.toro.exoplayer.Playable; +import im.ene.toro.media.PlaybackInfo; +import im.ene.toro.widget.Container; +import jp.wasabeef.glide.transformations.BlurTransformation; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; +import ml.docilealligator.infinityforreddit.FetchStreamableVideo; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SaveMemoryCenterInisdeDownsampleStrategy; +import ml.docilealligator.infinityforreddit.SaveThing; +import ml.docilealligator.infinityforreddit.StreamableVideo; +import ml.docilealligator.infinityforreddit.VoteThing; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.activities.FilteredPostsActivity; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewImageOrGifActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewRedditGalleryActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewVideoActivity; +import ml.docilealligator.infinityforreddit.apis.GfycatAPI; +import ml.docilealligator.infinityforreddit.apis.StreamableAPI; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.ShareLinkBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; +import ml.docilealligator.infinityforreddit.events.PostUpdateEventToPostDetailFragment; +import ml.docilealligator.infinityforreddit.fragments.HistoryPostFragment; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.post.PostPagingSource; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Call; +import retrofit2.Retrofit; + +public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerView.ViewHolder> implements CacheManager { + private static final int VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE = 1; + private static final int VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE = 2; + private static final int VIEW_TYPE_POST_CARD_TEXT_TYPE = 3; + private static final int VIEW_TYPE_POST_COMPACT = 4; + private static final int VIEW_TYPE_POST_GALLERY = 5; + private static final int VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE = 6; + private static final int VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE = 7; + private static final int VIEW_TYPE_POST_CARD_2_TEXT_TYPE = 8; + + private static final DiffUtil.ItemCallback<Post> DIFF_CALLBACK = new DiffUtil.ItemCallback<Post>() { + @Override + public boolean areItemsTheSame(@NonNull Post post, @NonNull Post t1) { + return post.getId().equals(t1.getId()); + } + + @Override + public boolean areContentsTheSame(@NonNull Post post, @NonNull Post t1) { + return false; + } + }; + + private BaseActivity mActivity; + private HistoryPostFragment mFragment; + private SharedPreferences mSharedPreferences; + private Executor mExecutor; + private Retrofit mOauthRetrofit; + private Retrofit mGfycatRetrofit; + private Retrofit mRedgifsRetrofit; + private Retrofit mStreamableRetrofit; + private String mAccessToken; + private RequestManager mGlide; + private int mMaxResolution; + private SaveMemoryCenterInisdeDownsampleStrategy mSaveMemoryCenterInsideDownsampleStrategy; + private Locale mLocale; + private boolean canStartActivity = true; + private int mPostType; + private int mPostLayout; + private int mDefaultLinkPostLayout; + private int mColorAccent; + private int mCardViewBackgroundColor; + private int mPrimaryTextColor; + private int mSecondaryTextColor; + private int mPostTitleColor; + private int mPostContentColor; + private int mStickiedPostIconTint; + private int mPostTypeBackgroundColor; + private int mPostTypeTextColor; + private int mSubredditColor; + private int mUsernameColor; + private int mSpoilerBackgroundColor; + private int mSpoilerTextColor; + private int mFlairBackgroundColor; + private int mFlairTextColor; + private int mAwardsBackgroundColor; + private int mAwardsTextColor; + private int mNSFWBackgroundColor; + private int mNSFWTextColor; + private int mArchivedIconTint; + private int mLockedIconTint; + private int mCrosspostIconTint; + private int mMediaIndicatorIconTint; + private int mMediaIndicatorBackgroundColor; + private int mNoPreviewPostTypeBackgroundColor; + private int mNoPreviewPostTypeIconTint; + private int mUpvotedColor; + private int mDownvotedColor; + private int mVoteAndReplyUnavailableVoteButtonColor; + private int mPostIconAndInfoColor; + private int mDividerColor; + private float mScale; + private boolean mDisplaySubredditName; + private boolean mVoteButtonsOnTheRight; + private boolean mNeedBlurNsfw; + private boolean mNeedBlurSpoiler; + private boolean mShowElapsedTime; + private String mTimeFormatPattern; + private boolean mShowDividerInCompactLayout; + private boolean mShowAbsoluteNumberOfVotes; + private boolean mAutoplay = false; + private boolean mAutoplayNsfwVideos; + private boolean mMuteAutoplayingVideos; + private boolean mShowThumbnailOnTheRightInCompactLayout; + private double mStartAutoplayVisibleAreaOffset; + private boolean mMuteNSFWVideo; + private boolean mAutomaticallyTryRedgifs; + private boolean mLongPressToHideToolbarInCompactLayout; + private boolean mCompactLayoutToolbarHiddenByDefault; + private boolean mDataSavingMode = false; + private boolean mDisableImagePreview; + private boolean mOnlyDisablePreviewInVideoAndGifPosts; + private boolean mHidePostType; + private boolean mHidePostFlair; + private boolean mHideTheNumberOfAwards; + private boolean mHideSubredditAndUserPrefix; + private boolean mHideTheNumberOfVotes; + private boolean mHideTheNumberOfComments; + private boolean mLegacyAutoplayVideoControllerUI; + private boolean mFixedHeightPreviewInCard; + private boolean mHideTextPostContent; + private boolean mEasierToWatchInFullScreen; + private Drawable mCommentIcon; + private ExoCreator mExoCreator; + private Callback mCallback; + private boolean canPlayVideo = true; + + public HistoryPostRecyclerViewAdapter(BaseActivity activity, HistoryPostFragment fragment, Executor executor, Retrofit oauthRetrofit, + Retrofit gfycatRetrofit, Retrofit redgifsRetrofit, Retrofit streambleRetrofit, + CustomThemeWrapper customThemeWrapper, Locale locale, + String accessToken, String accountName, int postType, int postLayout, boolean displaySubredditName, + SharedPreferences sharedPreferences, SharedPreferences nsfwAndSpoilerSharedPreferences, + SharedPreferences postHistorySharedPreferences, + ExoCreator exoCreator, Callback callback) { + super(DIFF_CALLBACK); + if (activity != null) { + mActivity = activity; + mFragment = fragment; + mSharedPreferences = sharedPreferences; + mExecutor = executor; + mOauthRetrofit = oauthRetrofit; + mGfycatRetrofit = gfycatRetrofit; + mRedgifsRetrofit = redgifsRetrofit; + mStreamableRetrofit = streambleRetrofit; + mAccessToken = accessToken; + mPostType = postType; + mDisplaySubredditName = displaySubredditName; + mNeedBlurNsfw = nsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, true); + mNeedBlurSpoiler = nsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_SPOILER_BASE, false); + mVoteButtonsOnTheRight = sharedPreferences.getBoolean(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY, false); + mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); + mTimeFormatPattern = sharedPreferences.getString(SharedPreferencesUtils.TIME_FORMAT_KEY, SharedPreferencesUtils.TIME_FORMAT_DEFAULT_VALUE); + mShowDividerInCompactLayout = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_DIVIDER_IN_COMPACT_LAYOUT, true); + mShowAbsoluteNumberOfVotes = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES, true); + String autoplayString = sharedPreferences.getString(SharedPreferencesUtils.VIDEO_AUTOPLAY, SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_NEVER); + int networkType = Utils.getConnectedNetwork(activity); + if (autoplayString.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ALWAYS_ON)) { + mAutoplay = true; + } else if (autoplayString.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ON_WIFI)) { + mAutoplay = networkType == Utils.NETWORK_TYPE_WIFI; + } + mAutoplayNsfwVideos = sharedPreferences.getBoolean(SharedPreferencesUtils.AUTOPLAY_NSFW_VIDEOS, true); + mMuteAutoplayingVideos = sharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_AUTOPLAYING_VIDEOS, true); + mShowThumbnailOnTheRightInCompactLayout = sharedPreferences.getBoolean( + SharedPreferencesUtils.SHOW_THUMBNAIL_ON_THE_LEFT_IN_COMPACT_LAYOUT, false); + + Resources resources = activity.getResources(); + mStartAutoplayVisibleAreaOffset = resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? + sharedPreferences.getInt(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT, 75) / 100.0 : + sharedPreferences.getInt(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_LANDSCAPE, 50) / 100.0; + + mMuteNSFWVideo = sharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_NSFW_VIDEO, false); + mAutomaticallyTryRedgifs = sharedPreferences.getBoolean(SharedPreferencesUtils.AUTOMATICALLY_TRY_REDGIFS, true); + + mLongPressToHideToolbarInCompactLayout = sharedPreferences.getBoolean(SharedPreferencesUtils.LONG_PRESS_TO_HIDE_TOOLBAR_IN_COMPACT_LAYOUT, false); + mCompactLayoutToolbarHiddenByDefault = sharedPreferences.getBoolean(SharedPreferencesUtils.POST_COMPACT_LAYOUT_TOOLBAR_HIDDEN_BY_DEFAULT, false); + + String dataSavingModeString = sharedPreferences.getString(SharedPreferencesUtils.DATA_SAVING_MODE, SharedPreferencesUtils.DATA_SAVING_MODE_OFF); + if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ALWAYS)) { + mDataSavingMode = true; + } else if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA)) { + mDataSavingMode = networkType == Utils.NETWORK_TYPE_CELLULAR; + } + mDisableImagePreview = sharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false); + mOnlyDisablePreviewInVideoAndGifPosts = sharedPreferences.getBoolean(SharedPreferencesUtils.ONLY_DISABLE_PREVIEW_IN_VIDEO_AND_GIF_POSTS, false); + + mHidePostType = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_POST_TYPE, false); + mHidePostFlair = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_POST_FLAIR, false); + mHideTheNumberOfAwards = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_AWARDS, false); + mHideSubredditAndUserPrefix = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_SUBREDDIT_AND_USER_PREFIX, false); + mHideTheNumberOfVotes = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_VOTES, false); + mHideTheNumberOfComments = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_COMMENTS, false); + mLegacyAutoplayVideoControllerUI = sharedPreferences.getBoolean(SharedPreferencesUtils.LEGACY_AUTOPLAY_VIDEO_CONTROLLER_UI, false); + mFixedHeightPreviewInCard = sharedPreferences.getBoolean(SharedPreferencesUtils.FIXED_HEIGHT_PREVIEW_IN_CARD, false); + mHideTextPostContent = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_TEXT_POST_CONTENT, false); + mEasierToWatchInFullScreen = sharedPreferences.getBoolean(SharedPreferencesUtils.EASIER_TO_WATCH_IN_FULL_SCREEN, false); + + mPostLayout = postLayout; + mDefaultLinkPostLayout = Integer.parseInt(sharedPreferences.getString(SharedPreferencesUtils.DEFAULT_LINK_POST_LAYOUT_KEY, "-1")); + + mColorAccent = customThemeWrapper.getColorAccent(); + mCardViewBackgroundColor = customThemeWrapper.getCardViewBackgroundColor(); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + mPostTitleColor = customThemeWrapper.getPostTitleColor(); + mPostContentColor = customThemeWrapper.getPostContentColor(); + mStickiedPostIconTint = customThemeWrapper.getStickiedPostIconTint(); + mPostTypeBackgroundColor = customThemeWrapper.getPostTypeBackgroundColor(); + mPostTypeTextColor = customThemeWrapper.getPostTypeTextColor(); + mSubredditColor = customThemeWrapper.getSubreddit(); + mUsernameColor = customThemeWrapper.getUsername(); + mSpoilerBackgroundColor = customThemeWrapper.getSpoilerBackgroundColor(); + mSpoilerTextColor = customThemeWrapper.getSpoilerTextColor(); + mFlairBackgroundColor = customThemeWrapper.getFlairBackgroundColor(); + mFlairTextColor = customThemeWrapper.getFlairTextColor(); + mAwardsBackgroundColor = customThemeWrapper.getAwardsBackgroundColor(); + mAwardsTextColor = customThemeWrapper.getAwardsTextColor(); + mNSFWBackgroundColor = customThemeWrapper.getNsfwBackgroundColor(); + mNSFWTextColor = customThemeWrapper.getNsfwTextColor(); + mArchivedIconTint = customThemeWrapper.getArchivedIconTint(); + mLockedIconTint = customThemeWrapper.getLockedIconTint(); + mCrosspostIconTint = customThemeWrapper.getCrosspostIconTint(); + mMediaIndicatorIconTint = customThemeWrapper.getMediaIndicatorIconColor(); + mMediaIndicatorBackgroundColor = customThemeWrapper.getMediaIndicatorBackgroundColor(); + mNoPreviewPostTypeBackgroundColor = customThemeWrapper.getNoPreviewPostTypeBackgroundColor(); + mNoPreviewPostTypeIconTint = customThemeWrapper.getNoPreviewPostTypeIconTint(); + mUpvotedColor = customThemeWrapper.getUpvoted(); + mDownvotedColor = customThemeWrapper.getDownvoted(); + mVoteAndReplyUnavailableVoteButtonColor = customThemeWrapper.getVoteAndReplyUnavailableButtonColor(); + mPostIconAndInfoColor = customThemeWrapper.getPostIconAndInfoColor(); + mDividerColor = customThemeWrapper.getDividerColor(); + + mCommentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); + if (mCommentIcon != null) { + DrawableCompat.setTint(mCommentIcon, mPostIconAndInfoColor); + } + + mScale = resources.getDisplayMetrics().density; + mGlide = Glide.with(mActivity); + mMaxResolution = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.POST_FEED_MAX_RESOLUTION, "5000000")); + mSaveMemoryCenterInsideDownsampleStrategy = new SaveMemoryCenterInisdeDownsampleStrategy(mMaxResolution); + mLocale = locale; + mExoCreator = exoCreator; + mCallback = callback; + } + } + + public void setCanStartActivity(boolean canStartActivity) { + this.canStartActivity = canStartActivity; + } + + @Override + public int getItemViewType(int position) { + if (mPostLayout == SharedPreferencesUtils.POST_LAYOUT_CARD) { + Post post = getItem(position); + if (post != null) { + switch (post.getPostType()) { + case Post.VIDEO_TYPE: + if (mAutoplay) { + if ((!mAutoplayNsfwVideos && post.isNSFW()) || post.isSpoiler()) { + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + } + return VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE; + } + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + case Post.GIF_TYPE: + case Post.IMAGE_TYPE: + case Post.GALLERY_TYPE: + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + case Post.LINK_TYPE: + case Post.NO_PREVIEW_LINK_TYPE: + switch (mDefaultLinkPostLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD_2: + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return VIEW_TYPE_POST_GALLERY; + case SharedPreferencesUtils.POST_LAYOUT_COMPACT: + return VIEW_TYPE_POST_COMPACT; + } + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + default: + return VIEW_TYPE_POST_CARD_TEXT_TYPE; + } + } + return VIEW_TYPE_POST_CARD_TEXT_TYPE; + } else if (mPostLayout == SharedPreferencesUtils.POST_LAYOUT_COMPACT) { + Post post = getItem(position); + if (post != null) { + if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + switch (mDefaultLinkPostLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD: + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return VIEW_TYPE_POST_GALLERY; + case SharedPreferencesUtils.POST_LAYOUT_CARD_2: + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + } + } + } + return VIEW_TYPE_POST_COMPACT; + } else if (mPostLayout == SharedPreferencesUtils.POST_LAYOUT_GALLERY) { + return VIEW_TYPE_POST_GALLERY; + } else { + Post post = getItem(position); + if (post != null) { + switch (post.getPostType()) { + case Post.VIDEO_TYPE: + if (mAutoplay) { + if ((!mAutoplayNsfwVideos && post.isNSFW()) || post.isSpoiler()) { + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + } + return VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE; + } + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + case Post.GIF_TYPE: + case Post.IMAGE_TYPE: + case Post.GALLERY_TYPE: + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + case Post.LINK_TYPE: + case Post.NO_PREVIEW_LINK_TYPE: + switch (mDefaultLinkPostLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD: + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return VIEW_TYPE_POST_GALLERY; + case SharedPreferencesUtils.POST_LAYOUT_COMPACT: + return VIEW_TYPE_POST_COMPACT; + } + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + default: + return VIEW_TYPE_POST_CARD_2_TEXT_TYPE; + } + } + return VIEW_TYPE_POST_CARD_2_TEXT_TYPE; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE) { + if (mDataSavingMode) { + return new PostWithPreviewTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_with_preview, parent, false)); + } + return new PostVideoAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(mLegacyAutoplayVideoControllerUI ? R.layout.item_post_video_type_autoplay_legacy_controller : R.layout.item_post_video_type_autoplay, parent, false)); + } else if (viewType == VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE) { + return new PostWithPreviewTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_with_preview, parent, false)); + } else if (viewType == VIEW_TYPE_POST_CARD_TEXT_TYPE) { + return new PostTextTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_text, parent, false)); + } else if (viewType == VIEW_TYPE_POST_COMPACT) { + if (mShowThumbnailOnTheRightInCompactLayout) { + return new PostCompactRightThumbnailViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_compact_right_thumbnail, parent, false)); + } else { + return new PostCompactLeftThumbnailViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_compact, parent, false)); + } + } else if (viewType == VIEW_TYPE_POST_GALLERY) { + return new PostGalleryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_gallery, parent, false)); + } else if (viewType == VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE) { + if (mDataSavingMode) { + return new PostCard2WithPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_card_2_with_preview, parent, false)); + } + return new PostCard2VideoAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(mLegacyAutoplayVideoControllerUI ? R.layout.item_post_card_2_video_autoplay_legacy_controller : R.layout.item_post_card_2_video_autoplay, parent, false)); + } else if (viewType == VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE) { + return new PostCard2WithPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_card_2_with_preview, parent, false)); + } else { + //VIEW_TYPE_POST_CARD_2_TEXT_TYPE + return new PostCard2TextTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_card_2_text, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { + if (holder instanceof PostBaseViewHolder) { + Post post = getItem(position); + if (post != null) { + ((PostBaseViewHolder) holder).post = post; + String authorPrefixed = "u/" + post.getAuthor(); + + if (mHideSubredditAndUserPrefix) { + ((PostBaseViewHolder) holder).subredditTextView.setText(post.getSubredditName()); + ((PostBaseViewHolder) holder).userTextView.setText(post.getAuthor()); + } else { + ((PostBaseViewHolder) holder).subredditTextView.setText("r/" + post.getSubredditName()); + ((PostBaseViewHolder) holder).userTextView.setText(authorPrefixed); + } + + if (mDisplaySubredditName) { + if (authorPrefixed.equals(post.getSubredditNamePrefixed())) { + if (post.getAuthorIconUrl() == null) { + mFragment.loadIcon(post.getAuthor(), false, (subredditOrUserName, iconUrl) -> { + if (mActivity != null && getItemCount() > 0 && post.getAuthor().equals(subredditOrUserName)) { + if (iconUrl == null || iconUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getBindingAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconUrl); + } + } + }); + } 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(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + } else { + if (post.getSubredditIconUrl() == null) { + mFragment.loadIcon(post.getSubredditName(), true, (subredditOrUserName, iconUrl) -> { + if (mActivity != null && getItemCount() > 0 && post.getSubredditName().equals(subredditOrUserName)) { + if (iconUrl == null || iconUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getBindingAdapterPosition() >= 0) { + post.setSubredditIconUrl(iconUrl); + } + } + }); + } 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(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + } + } else { + if (post.getAuthorIconUrl() == null) { + String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditName() : post.getAuthor(); + mFragment.loadIcon(authorName, post.getAuthor().equals("[deleted]"), (subredditOrUserName, iconUrl) -> { + if (mActivity != null && getItemCount() > 0) { + if (iconUrl == null || iconUrl.equals("") && authorName.equals(subredditOrUserName)) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getBindingAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconUrl); + } + } + }); + } 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(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + } + + if (mShowElapsedTime) { + ((PostBaseViewHolder) holder).postTimeTextView.setText( + Utils.getElapsedTime(mActivity, post.getPostTimeMillis())); + } else { + ((PostBaseViewHolder) holder).postTimeTextView.setText(Utils.getFormattedTime(mLocale, post.getPostTimeMillis(), mTimeFormatPattern)); + } + + ((PostBaseViewHolder) holder).titleTextView.setText(post.getTitle()); + if (!mHideTheNumberOfVotes) { + ((PostBaseViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } else { + ((PostBaseViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.vote)); + } + + if (post.isLocked()) { + ((PostBaseViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); + } + + if (post.isNSFW()) { + ((PostBaseViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); + } + + if (post.isSpoiler()) { + ((PostBaseViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE); + } + + if (post.getFlair() != null && !post.getFlair().equals("")) { + if (mHidePostFlair) { + ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.GONE); + } else { + ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostBaseViewHolder) holder).flairTextView, post.getFlair(), false); + } + } + + if (post.getNAwards() > 0 && !mHideTheNumberOfAwards) { + ((PostBaseViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + if (post.getNAwards() == 1) { + ((PostBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.one_award)); + } else { + ((PostBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.n_awards, post.getNAwards())); + } + } + + switch (post.getVoteType()) { + case 1: + //Upvoted + ((PostBaseViewHolder) holder).upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + break; + case -1: + //Downvoted + ((PostBaseViewHolder) holder).downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + break; + } + + if (mPostType == PostPagingSource.TYPE_SUBREDDIT && !mDisplaySubredditName && post.isStickied()) { + ((PostBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostBaseViewHolder) holder).stickiedPostImageView); + } + + if (post.isArchived()) { + ((PostBaseViewHolder) holder).archivedImageView.setVisibility(View.VISIBLE); + + ((PostBaseViewHolder) holder).upvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostBaseViewHolder) holder).downvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (post.isCrosspost()) { + ((PostBaseViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); + } + + if (!mHideTheNumberOfComments) { + ((PostBaseViewHolder) holder).commentsCountTextView.setVisibility(View.VISIBLE); + ((PostBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(post.getNComments())); + } else { + ((PostBaseViewHolder) holder).commentsCountTextView.setVisibility(View.GONE); + } + + if (post.isSaved()) { + ((PostBaseViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((PostBaseViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + + if (mHidePostType) { + ((PostBaseViewHolder) holder).typeTextView.setVisibility(View.GONE); + } else { + ((PostBaseViewHolder) holder).typeTextView.setVisibility(View.VISIBLE); + } + + if (holder instanceof PostVideoAutoplayViewHolder) { + ((PostVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); + Post.Preview preview = getSuitablePreview(post.getPreviews()); + if (!mFixedHeightPreviewInCard && preview != null) { + ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); + mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostVideoAutoplayViewHolder) holder).previewImageView); + } else { + ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); + } + if (mFragment.getMasterMutingOption() == null) { + ((PostVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + } else { + ((PostVideoAutoplayViewHolder) holder).setVolume(mFragment.getMasterMutingOption() ? 0f : 1f); + } + + if ((post.isGfycat() || post.isRedgifs()) && !post.isLoadGfycatOrStreamableVideoSuccess()) { + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = + (post.isGfycat() ? mGfycatRetrofit : mRedgifsRetrofit).create(GfycatAPI.class).getGfycatData(post.getGfycatId()); + FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall, post.getGfycatId(), + post.isGfycat(), mAutomaticallyTryRedgifs, + new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { + @Override + public void success(String webm, String mp4) { + post.setVideoDownloadUrl(mp4); + post.setVideoUrl(mp4); + post.setLoadGfyOrStreamableVideoSuccess(true); + if (position == holder.getBindingAdapterPosition()) { + ((PostVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } + + @Override + public void failed(int errorCode) { + if (position == holder.getBindingAdapterPosition()) { + ((PostVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + } + }); + } else if(post.isStreamable() && !post.isLoadGfycatOrStreamableVideoSuccess()) { + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = + mStreamableRetrofit.create(StreamableAPI.class).getStreamableData(post.getStreamableShortCode()); + FetchStreamableVideo.fetchStreamableVideoInRecyclerViewAdapter(mExecutor, new Handler(), + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall, + new FetchStreamableVideo.FetchStreamableVideoListener() { + @Override + public void success(StreamableVideo streamableVideo) { + StreamableVideo.Media media = streamableVideo.mp4 == null ? streamableVideo.mp4Mobile : streamableVideo.mp4; + post.setVideoDownloadUrl(media.url); + post.setVideoUrl(media.url); + post.setLoadGfyOrStreamableVideoSuccess(true); + if (position == holder.getBindingAdapterPosition()) { + ((PostVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } + + @Override + public void failed() { + if (position == holder.getBindingAdapterPosition()) { + ((PostVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + } + }); + } else { + ((PostVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } else if (holder instanceof PostWithPreviewTypeViewHolder) { + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.video)); + } else if (post.getPostType() == Post.GIF_TYPE) { + if (!mAutoplay) { + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + } + ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gif)); + } else if (post.getPostType() == Post.IMAGE_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.image)); + } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.link)); + ((PostWithPreviewTypeViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); + String domain = Uri.parse(post.getUrl()).getHost(); + ((PostWithPreviewTypeViewHolder) holder).linkTextView.setText(domain); + if (post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); + } + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gallery)); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_gallery_24dp)); + } + + if (post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + } + + if (mDataSavingMode && mDisableImagePreview) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + } else if (mDataSavingMode && mOnlyDisablePreviewInVideoAndGifPosts && (post.getPostType() == Post.VIDEO_TYPE || post.getPostType() == Post.GIF_TYPE)) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else { + if (post.getPostType() == Post.GIF_TYPE && ((post.isNSFW() && mNeedBlurNsfw && !(mAutoplay && mAutoplayNsfwVideos)) || (post.isSpoiler() && mNeedBlurSpoiler))) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else { + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostWithPreviewTypeViewHolder) holder).preview = preview; + if (preview != null) { + ((PostWithPreviewTypeViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.VISIBLE); + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostWithPreviewTypeViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = height; + } else { + ((PostWithPreviewTypeViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostWithPreviewTypeViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + ((PostWithPreviewTypeViewHolder) holder).imageView.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + } + } + } + } else if (holder instanceof PostTextTypeViewHolder) { + if (!mHideTextPostContent && !post.isSpoiler() && post.getSelfTextPlainTrimmed() != null && !post.getSelfTextPlainTrimmed().equals("")) { + ((PostTextTypeViewHolder) holder).contentTextView.setVisibility(View.VISIBLE); + ((PostTextTypeViewHolder) holder).contentTextView.setText(post.getSelfTextPlainTrimmed()); + } + } else if (holder instanceof PostCard2VideoAutoplayViewHolder) { + ((PostCard2VideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); + Post.Preview preview = getSuitablePreview(post.getPreviews()); + if (!mFixedHeightPreviewInCard && preview != null) { + ((PostCard2VideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); + mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostCard2VideoAutoplayViewHolder) holder).previewImageView); + } else { + ((PostCard2VideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); + } + if (mFragment.getMasterMutingOption() == null) { + ((PostCard2VideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + } else { + ((PostCard2VideoAutoplayViewHolder) holder).setVolume(mFragment.getMasterMutingOption() ? 0f : 1f); + } + + if ((post.isGfycat() || post.isRedgifs()) && !post.isLoadGfycatOrStreamableVideoSuccess()) { + ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = + (post.isGfycat() ? mGfycatRetrofit : mRedgifsRetrofit).create(GfycatAPI.class).getGfycatData(post.getGfycatId()); + FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), + ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall, post.getGfycatId(), + post.isGfycat(), mAutomaticallyTryRedgifs, + new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { + @Override + public void success(String webm, String mp4) { + post.setVideoDownloadUrl(mp4); + post.setVideoUrl(mp4); + post.setLoadGfyOrStreamableVideoSuccess(true); + if (position == holder.getBindingAdapterPosition()) { + ((PostCard2VideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } + + @Override + public void failed(int errorCode) { + if (position == holder.getBindingAdapterPosition()) { + ((PostCard2VideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + } + }); + } else if(post.isStreamable() && !post.isLoadGfycatOrStreamableVideoSuccess()) { + ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = + mStreamableRetrofit.create(StreamableAPI.class).getStreamableData(post.getStreamableShortCode()); + FetchStreamableVideo.fetchStreamableVideoInRecyclerViewAdapter(mExecutor, new Handler(), + ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall, + new FetchStreamableVideo.FetchStreamableVideoListener() { + @Override + public void success(StreamableVideo streamableVideo) { + StreamableVideo.Media media = streamableVideo.mp4 == null ? streamableVideo.mp4Mobile : streamableVideo.mp4; + post.setVideoDownloadUrl(media.url); + post.setVideoUrl(media.url); + post.setLoadGfyOrStreamableVideoSuccess(true); + if (position == holder.getBindingAdapterPosition()) { + ((PostCard2VideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } + + @Override + public void failed() { + if (position == holder.getBindingAdapterPosition()) { + ((PostCard2VideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + } + }); + } else { + ((PostCard2VideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } else if (holder instanceof PostCard2WithPreviewViewHolder) { + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.video)); + } else if (post.getPostType() == Post.GIF_TYPE) { + if (!mAutoplay) { + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + } + ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gif)); + } else if (post.getPostType() == Post.IMAGE_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.image)); + } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.link)); + ((PostCard2WithPreviewViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); + String domain = Uri.parse(post.getUrl()).getHost(); + ((PostCard2WithPreviewViewHolder) holder).linkTextView.setText(domain); + if (post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); + } + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gallery)); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_gallery_24dp)); + } + + if (post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + } + + if (mDataSavingMode && mDisableImagePreview) { + ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + } else if (mDataSavingMode && mOnlyDisablePreviewInVideoAndGifPosts && (post.getPostType() == Post.VIDEO_TYPE || post.getPostType() == Post.GIF_TYPE)) { + ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else { + if (post.getPostType() == Post.GIF_TYPE && ((post.isNSFW() && mNeedBlurNsfw && !(mAutoplay && mAutoplayNsfwVideos)) || (post.isSpoiler() && mNeedBlurSpoiler))) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else { + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostCard2WithPreviewViewHolder) holder).preview = preview; + if (preview != null) { + ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.VISIBLE); + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostCard2WithPreviewViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostCard2WithPreviewViewHolder) holder).imageView.getLayoutParams().height = height; + } else { + ((PostCard2WithPreviewViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostCard2WithPreviewViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + ((PostCard2WithPreviewViewHolder) holder).imageView.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + } + } + + } + } else if (holder instanceof PostCard2TextTypeViewHolder) { + if (!mHideTextPostContent && !post.isSpoiler() && post.getSelfTextPlainTrimmed() != null && !post.getSelfTextPlainTrimmed().equals("")) { + ((PostCard2TextTypeViewHolder) holder).contentTextView.setVisibility(View.VISIBLE); + ((PostCard2TextTypeViewHolder) holder).contentTextView.setText(post.getSelfTextPlainTrimmed()); + } + } + mCallback.currentlyBindItem(holder.getBindingAdapterPosition()); + } + } else if (holder instanceof PostCompactBaseViewHolder) { + Post post = getItem(position); + if (post != null) { + ((PostCompactBaseViewHolder) holder).post = post; + final String subredditNamePrefixed = post.getSubredditNamePrefixed(); + String subredditName = subredditNamePrefixed.substring(2); + String authorPrefixed = "u/" + post.getAuthor(); + final String title = post.getTitle(); + int voteType = post.getVoteType(); + boolean nsfw = post.isNSFW(); + boolean spoiler = post.isSpoiler(); + String flair = post.getFlair(); + int nAwards = post.getNAwards(); + boolean isArchived = post.isArchived(); + + if (mDisplaySubredditName) { + if (authorPrefixed.equals(subredditNamePrefixed)) { + if (post.getAuthorIconUrl() == null) { + mFragment.loadIcon(post.getAuthor(), false, (subredditOrUserName, iconUrl) -> { + if (mActivity != null && getItemCount() > 0 && post.getAuthor().equals(subredditOrUserName)) { + if (iconUrl == null || iconUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getBindingAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconUrl); + } + } + }); + } 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(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + } else { + if (post.getSubredditIconUrl() == null) { + mFragment.loadIcon(subredditName, true, (subredditOrUserName, iconUrl) -> { + if (mActivity != null && getItemCount() > 0 && subredditName.equals(subredditOrUserName)) { + if (iconUrl == null || iconUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getBindingAdapterPosition() >= 0) { + post.setSubredditIconUrl(iconUrl); + } + } + }); + } 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(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + } + + ((PostCompactBaseViewHolder) holder).nameTextView.setTextColor(mSubredditColor); + if (mHideSubredditAndUserPrefix) { + ((PostCompactBaseViewHolder) holder).nameTextView.setText(post.getSubredditName()); + } else { + ((PostCompactBaseViewHolder) holder).nameTextView.setText("r/" + post.getSubredditName()); + } + } else { + if (post.getAuthorIconUrl() == null) { + String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditName() : post.getAuthor(); + mFragment.loadIcon(authorName, post.getAuthor().equals("[deleted]"), (subredditOrUserName, iconUrl) -> { + if (mActivity != null && getItemCount() > 0 && authorName.equals(subredditOrUserName)) { + if (iconUrl == null || iconUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getBindingAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconUrl); + } + } + }); + } 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(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + ((PostCompactBaseViewHolder) holder).nameTextView.setTextColor(mUsernameColor); + if (mHideSubredditAndUserPrefix) { + ((PostCompactBaseViewHolder) holder).nameTextView.setText(post.getAuthor()); + } else { + ((PostCompactBaseViewHolder) holder).nameTextView.setText(authorPrefixed); + } + } + + if (mShowElapsedTime) { + ((PostCompactBaseViewHolder) holder).postTimeTextView.setText( + Utils.getElapsedTime(mActivity, post.getPostTimeMillis())); + } else { + ((PostCompactBaseViewHolder) holder).postTimeTextView.setText(Utils.getFormattedTime(mLocale, post.getPostTimeMillis(), mTimeFormatPattern)); + } + + if (mCompactLayoutToolbarHiddenByDefault) { + ViewGroup.LayoutParams params = ((PostCompactBaseViewHolder) holder).bottomConstraintLayout.getLayoutParams(); + params.height = 0; + ((PostCompactBaseViewHolder) holder).bottomConstraintLayout.setLayoutParams(params); + } else { + ViewGroup.LayoutParams params = ((PostCompactBaseViewHolder) holder).bottomConstraintLayout.getLayoutParams(); + params.height = LinearLayout.LayoutParams.WRAP_CONTENT; + ((PostCompactBaseViewHolder) holder).bottomConstraintLayout.setLayoutParams(params); + } + + if (mShowDividerInCompactLayout) { + ((PostCompactBaseViewHolder) holder).divider.setVisibility(View.VISIBLE); + } else { + ((PostCompactBaseViewHolder) holder).divider.setVisibility(View.GONE); + } + + ((PostCompactBaseViewHolder) holder).titleTextView.setText(title); + if (!mHideTheNumberOfVotes) { + ((PostCompactBaseViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } else { + ((PostCompactBaseViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.vote)); + } + + if (post.isLocked()) { + ((PostCompactBaseViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); + } + + if (nsfw) { + ((PostCompactBaseViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); + } + + if (spoiler) { + ((PostCompactBaseViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE); + } + + if (flair != null && !flair.equals("")) { + if (mHidePostFlair) { + ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.GONE); + } else { + ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostCompactBaseViewHolder) holder).flairTextView, flair, false); + } + } + + if (nAwards > 0 && !mHideTheNumberOfAwards) { + ((PostCompactBaseViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + if (nAwards == 1) { + ((PostCompactBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.one_award)); + } else { + ((PostCompactBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.n_awards, nAwards)); + } + } + + switch (voteType) { + case 1: + //Upvoted + ((PostCompactBaseViewHolder) holder).upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + break; + case -1: + //Downvoted + ((PostCompactBaseViewHolder) holder).downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + break; + } + + if (post.getPostType() != Post.TEXT_TYPE && post.getPostType() != Post.NO_PREVIEW_LINK_TYPE && !(mDataSavingMode && mDisableImagePreview)) { + ((PostCompactBaseViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.GALLERY_TYPE && post.getPreviews() != null && post.getPreviews().isEmpty()) { + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + if (post.getPreviews() != null && !post.getPreviews().isEmpty()) { + ((PostCompactBaseViewHolder) holder).imageView.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + loadImage(holder); + } + } + + if (mPostType == PostPagingSource.TYPE_SUBREDDIT && !mDisplaySubredditName && post.isStickied()) { + ((PostCompactBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostCompactBaseViewHolder) holder).stickiedPostImageView); + } + + if (isArchived) { + ((PostCompactBaseViewHolder) holder).archivedImageView.setVisibility(View.VISIBLE); + + ((PostCompactBaseViewHolder) holder).upvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactBaseViewHolder) holder).downvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (post.isCrosspost()) { + ((PostCompactBaseViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); + } + + if (mHidePostType) { + ((PostCompactBaseViewHolder) holder).typeTextView.setVisibility(View.GONE); + } else { + ((PostCompactBaseViewHolder) holder).typeTextView.setVisibility(View.VISIBLE); + } + + switch (post.getPostType()) { + case Post.IMAGE_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.image); + if (mDataSavingMode && mDisableImagePreview) { + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_image_24dp); + } + break; + case Post.LINK_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.link); + if (mDataSavingMode && mDisableImagePreview) { + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_link); + } + + ((PostCompactBaseViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); + String domain = Uri.parse(post.getUrl()).getHost(); + ((PostCompactBaseViewHolder) holder).linkTextView.setText(domain); + break; + case Post.GIF_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.gif); + if (mDataSavingMode && (mDisableImagePreview || mOnlyDisablePreviewInVideoAndGifPosts)) { + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_image_24dp); + } else { + ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).playButtonImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_24dp)); + } + break; + case Post.VIDEO_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.video); + if (mDataSavingMode && (mDisableImagePreview || mOnlyDisablePreviewInVideoAndGifPosts)) { + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_outline_video_24dp); + } else { + ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).playButtonImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_24dp)); + } + break; + case Post.NO_PREVIEW_LINK_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.link); + + String noPreviewLinkUrl = post.getUrl(); + ((PostCompactBaseViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); + String noPreviewLinkDomain = Uri.parse(noPreviewLinkUrl).getHost(); + ((PostCompactBaseViewHolder) holder).linkTextView.setText(noPreviewLinkDomain); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_link); + break; + case Post.GALLERY_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.gallery); + if (mDataSavingMode && mDisableImagePreview) { + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_gallery_24dp); + } else { + ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).playButtonImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_gallery_24dp)); + } + break; + case Post.TEXT_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.text); + break; + } + + if (!mHideTheNumberOfComments) { + ((PostCompactBaseViewHolder) holder).commentsCountTextView.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(post.getNComments())); + } else { + ((PostCompactBaseViewHolder) holder).commentsCountTextView.setVisibility(View.GONE); + } + + if (post.isSaved()) { + ((PostCompactBaseViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((PostCompactBaseViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + + mCallback.currentlyBindItem(holder.getBindingAdapterPosition()); + } + } else if (holder instanceof PostGalleryViewHolder) { + Post post = getItem(position); + if (post != null) { + ((PostGalleryViewHolder) holder).post = post; + + switch (post.getPostType()) { + case Post.IMAGE_TYPE: { + ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostGalleryViewHolder) holder).preview = preview; + if (preview != null) { + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; + } else { + ((PostGalleryViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); + } + break; + } + case Post.GIF_TYPE: { + if (post.getPostType() == Post.GIF_TYPE && ((post.isNSFW() && mNeedBlurNsfw && !(mAutoplay && mAutoplayNsfwVideos)) || (post.isSpoiler() && mNeedBlurSpoiler))) { + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); + } else { + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostGalleryViewHolder) holder).preview = preview; + if (preview != null) { + ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; + } else { + ((PostGalleryViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); + } + } + break; + } + case Post.VIDEO_TYPE: { + ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostGalleryViewHolder) holder).preview = preview; + if (preview != null) { + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; + } else { + ((PostGalleryViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_outline_video_24dp); + } + break; + } + case Post.LINK_TYPE: { + ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_link_post_type_indicator)); + + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostGalleryViewHolder) holder).preview = preview; + if (preview != null) { + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; + } else { + ((PostGalleryViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); + } + break; + } + case Post.NO_PREVIEW_LINK_TYPE: { + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); + break; + } + case Post.TEXT_TYPE: { + ((PostGalleryViewHolder) holder).titleTextView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).titleTextView.setText(post.getTitle()); + break; + } + case Post.GALLERY_TYPE: { + ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_gallery_24dp)); + + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostGalleryViewHolder) holder).preview = preview; + if (preview != null) { + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; + } else { + ((PostGalleryViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + break; + } + } + } + } + } + + @Nullable + private Post.Preview getSuitablePreview(ArrayList<Post.Preview> previews) { + Post.Preview preview; + if (!previews.isEmpty()) { + int previewIndex; + if (mDataSavingMode && previews.size() > 2) { + previewIndex = previews.size() / 2; + } else { + previewIndex = 0; + } + preview = previews.get(previewIndex); + if (preview.getPreviewWidth() * preview.getPreviewHeight() > mMaxResolution) { + for (int i = previews.size() - 1; i >= 1; i--) { + preview = previews.get(i); + if (preview.getPreviewWidth() * preview.getPreviewHeight() <= mMaxResolution) { + return preview; + } + } + } + return preview; + } + + return null; + } + + private void loadImage(final RecyclerView.ViewHolder holder) { + if (holder instanceof PostWithPreviewTypeViewHolder) { + Post post = ((PostWithPreviewTypeViewHolder) holder).post; + Post.Preview preview = ((PostWithPreviewTypeViewHolder) holder).preview; + if (preview != null) { + String url; + boolean blurImage = (post.isNSFW() && mNeedBlurNsfw && !(post.getPostType() == Post.GIF_TYPE && mAutoplay && mAutoplayNsfwVideos)) || (post.isSpoiler() && mNeedBlurSpoiler); + if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { + url = post.getUrl(); + } else { + url = preview.getPreviewUrl(); + } + RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(url).listener(((PostWithPreviewTypeViewHolder) holder).glideRequestListener); + if (blurImage) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) + .into(((PostWithPreviewTypeViewHolder) holder).imageView); + } else { + imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostWithPreviewTypeViewHolder) holder).imageView); + } + } + } else if (holder instanceof PostCompactBaseViewHolder) { + Post post = ((PostCompactBaseViewHolder) holder).post; + String postCompactThumbnailPreviewUrl; + ArrayList<Post.Preview> previews = post.getPreviews(); + if (previews != null && !previews.isEmpty()) { + if (previews.size() >= 2) { + postCompactThumbnailPreviewUrl = previews.get(1).getPreviewUrl(); + } else { + postCompactThumbnailPreviewUrl = previews.get(0).getPreviewUrl(); + } + + RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(postCompactThumbnailPreviewUrl) + .error(R.drawable.ic_error_outline_black_24dp).listener(((PostCompactBaseViewHolder) holder).requestListener); + if ((post.isNSFW() && mNeedBlurNsfw) || (post.isSpoiler() && mNeedBlurSpoiler)) { + imageRequestBuilder + .transform(new BlurTransformation(50, 2)).into(((PostCompactBaseViewHolder) holder).imageView); + } else { + imageRequestBuilder.into(((PostCompactBaseViewHolder) holder).imageView); + } + } + } else if (holder instanceof PostGalleryViewHolder) { + Post post = ((PostGalleryViewHolder) holder).post; + Post.Preview preview = ((PostGalleryViewHolder) holder).preview; + if (preview != null) { + String url; + boolean blurImage = (post.isNSFW() && mNeedBlurNsfw && !(post.getPostType() == Post.GIF_TYPE && mAutoplay && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler; + if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { + url = post.getUrl(); + } else { + url = preview.getPreviewUrl(); + } + RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(url).listener(((PostGalleryViewHolder) holder).requestListener); + + if (blurImage) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) + .into(((PostGalleryViewHolder) holder).imageView); + } else { + imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostGalleryViewHolder) holder).imageView); + } + } + } else if (holder instanceof PostCard2WithPreviewViewHolder) { + Post post = ((PostCard2WithPreviewViewHolder) holder).post; + Post.Preview preview = ((PostCard2WithPreviewViewHolder) holder).preview; + if (preview != null) { + String url; + boolean blurImage = (post.isNSFW() && mNeedBlurNsfw && !(post.getPostType() == Post.GIF_TYPE && mAutoplay && mAutoplayNsfwVideos)) || (post.isSpoiler() && mNeedBlurSpoiler); + if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { + url = post.getUrl(); + } else { + url = preview.getPreviewUrl(); + } + RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(url).listener(((PostCard2WithPreviewViewHolder) holder).requestListener); + + if (blurImage) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) + .into(((PostCard2WithPreviewViewHolder) holder).imageView); + } else { + imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostCard2WithPreviewViewHolder) holder).imageView); + } + } + } + } + + private void shareLink(Post post) { + Bundle bundle = new Bundle(); + bundle.putString(ShareLinkBottomSheetFragment.EXTRA_POST_LINK, post.getPermalink()); + if (post.getPostType() != Post.TEXT_TYPE) { + bundle.putInt(ShareLinkBottomSheetFragment.EXTRA_MEDIA_TYPE, post.getPostType()); + switch (post.getPostType()) { + case Post.IMAGE_TYPE: + case Post.GIF_TYPE: + case Post.LINK_TYPE: + case Post.NO_PREVIEW_LINK_TYPE: + bundle.putString(ShareLinkBottomSheetFragment.EXTRA_MEDIA_LINK, post.getUrl()); + break; + case Post.VIDEO_TYPE: + bundle.putString(ShareLinkBottomSheetFragment.EXTRA_MEDIA_LINK, post.getVideoDownloadUrl()); + break; + } + } + ShareLinkBottomSheetFragment shareLinkBottomSheetFragment = new ShareLinkBottomSheetFragment(); + shareLinkBottomSheetFragment.setArguments(bundle); + shareLinkBottomSheetFragment.show(mActivity.getSupportFragmentManager(), shareLinkBottomSheetFragment.getTag()); + } + + @Nullable + public Post getItemByPosition(int position) { + if (position >= 0 && super.getItemCount() > position) { + return super.getItem(position); + } + + return null; + } + + public void setVoteButtonsPosition(boolean voteButtonsOnTheRight) { + mVoteButtonsOnTheRight = voteButtonsOnTheRight; + } + + public void setPostLayout(int postLayout) { + mPostLayout = postLayout; + } + + public void setBlurNsfwAndDoNotBlurNsfwInNsfwSubreddits(boolean needBlurNsfw) { + mNeedBlurNsfw = needBlurNsfw; + } + + public void setBlurSpoiler(boolean needBlurSpoiler) { + mNeedBlurSpoiler = needBlurSpoiler; + } + + public void setShowElapsedTime(boolean showElapsedTime) { + mShowElapsedTime = showElapsedTime; + } + + public void setTimeFormat(String timeFormat) { + mTimeFormatPattern = timeFormat; + } + + public void setShowDividerInCompactLayout(boolean showDividerInCompactLayout) { + mShowDividerInCompactLayout = showDividerInCompactLayout; + } + + public void setShowAbsoluteNumberOfVotes(boolean showAbsoluteNumberOfVotes) { + mShowAbsoluteNumberOfVotes = showAbsoluteNumberOfVotes; + } + + public int getNextItemPositionWithoutBeingHidden(int fromPosition) { + int temp = fromPosition; + while (temp >= 0 && temp < super.getItemCount()) { + Post post = getItem(temp); + if (post != null && post.isHiddenInRecyclerView()) { + temp++; + } else { + break; + } + } + + return temp; + } + + public void setAutoplay(boolean autoplay) { + mAutoplay = autoplay; + } + + public boolean isAutoplay() { + return mAutoplay; + } + + public void setAutoplayNsfwVideos(boolean autoplayNsfwVideos) { + mAutoplayNsfwVideos = autoplayNsfwVideos; + } + + public void setMuteAutoplayingVideos(boolean muteAutoplayingVideos) { + mMuteAutoplayingVideos = muteAutoplayingVideos; + } + + public void setShowThumbnailOnTheRightInCompactLayout(boolean showThumbnailOnTheRightInCompactLayout) { + mShowThumbnailOnTheRightInCompactLayout = showThumbnailOnTheRightInCompactLayout; + } + + public void setStartAutoplayVisibleAreaOffset(double startAutoplayVisibleAreaOffset) { + this.mStartAutoplayVisibleAreaOffset = startAutoplayVisibleAreaOffset / 100.0; + } + + public void setMuteNSFWVideo(boolean muteNSFWVideo) { + this.mMuteNSFWVideo = muteNSFWVideo; + } + + public void setLongPressToHideToolbarInCompactLayout(boolean longPressToHideToolbarInCompactLayout) { + mLongPressToHideToolbarInCompactLayout = longPressToHideToolbarInCompactLayout; + } + + public void setCompactLayoutToolbarHiddenByDefault(boolean compactLayoutToolbarHiddenByDefault) { + mCompactLayoutToolbarHiddenByDefault = compactLayoutToolbarHiddenByDefault; + } + + public void setDataSavingMode(boolean dataSavingMode) { + mDataSavingMode = dataSavingMode; + } + + public void setDisableImagePreview(boolean disableImagePreview) { + mDisableImagePreview = disableImagePreview; + } + + public void setOnlyDisablePreviewInVideoPosts(boolean onlyDisablePreviewInVideoAndGifPosts) { + mOnlyDisablePreviewInVideoAndGifPosts = onlyDisablePreviewInVideoAndGifPosts; + } + + public void setHidePostType(boolean hidePostType) { + mHidePostType = hidePostType; + } + + public void setHidePostFlair(boolean hidePostFlair) { + mHidePostFlair = hidePostFlair; + } + + public void setHideTheNumberOfAwards(boolean hideTheNumberOfAwards) { + mHideTheNumberOfAwards = hideTheNumberOfAwards; + } + + public void setHideSubredditAndUserPrefix(boolean hideSubredditAndUserPrefix) { + mHideSubredditAndUserPrefix = hideSubredditAndUserPrefix; + } + + public void setHideTheNumberOfVotes(boolean hideTheNumberOfVotes) { + mHideTheNumberOfVotes = hideTheNumberOfVotes; + } + + public void setHideTheNumberOfComments(boolean hideTheNumberOfComments) { + mHideTheNumberOfComments = hideTheNumberOfComments; + } + + public void setDefaultLinkPostLayout(int defaultLinkPostLayout) { + mDefaultLinkPostLayout = defaultLinkPostLayout; + } + + public void setFixedHeightPreviewInCard(boolean fixedHeightPreviewInCard) { + mFixedHeightPreviewInCard = fixedHeightPreviewInCard; + } + + public void setHideTextPostContent(boolean hideTextPostContent) { + mHideTextPostContent = hideTextPostContent; + } + + public void setPostFeedMaxResolution(int postFeedMaxResolution) { + mMaxResolution = postFeedMaxResolution; + if (mSaveMemoryCenterInsideDownsampleStrategy != null) { + mSaveMemoryCenterInsideDownsampleStrategy.setThreshold(postFeedMaxResolution); + } + } + + public void setEasierToWatchInFullScreen(boolean easierToWatchInFullScreen) { + this.mEasierToWatchInFullScreen = easierToWatchInFullScreen; + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if (holder instanceof PostBaseViewHolder) { + if (((PostBaseViewHolder) holder).itemViewIsNotCardView) { + holder.itemView.setBackgroundColor(mCardViewBackgroundColor); + } else { + holder.itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + } + mGlide.clear(((PostBaseViewHolder) holder).iconGifImageView); + ((PostBaseViewHolder) holder).titleTextView.setTextColor(mPostTitleColor); + if (holder instanceof PostVideoAutoplayViewHolder) { + ((PostVideoAutoplayViewHolder) holder).mediaUri = null; + if (((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall != null && !((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall.isCanceled()) { + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall.cancel(); + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = null; + } + ((PostVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.GONE); + ((PostVideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); + ((PostVideoAutoplayViewHolder) holder).resetVolume(); + mGlide.clear(((PostVideoAutoplayViewHolder) holder).previewImageView); + ((PostVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); + } else if (holder instanceof PostWithPreviewTypeViewHolder) { + mGlide.clear(((PostWithPreviewTypeViewHolder) holder).imageView); + ((PostWithPreviewTypeViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).errorTextView.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).linkTextView.setVisibility(View.GONE); + } else if (holder instanceof PostTextTypeViewHolder) { + ((PostTextTypeViewHolder) holder).contentTextView.setText(""); + ((PostTextTypeViewHolder) holder).contentTextView.setTextColor(mPostContentColor); + ((PostTextTypeViewHolder) holder).contentTextView.setVisibility(View.GONE); + } else if (holder instanceof PostCard2VideoAutoplayViewHolder) { + ((PostCard2VideoAutoplayViewHolder) holder).mediaUri = null; + if (((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall != null && !((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall.isCanceled()) { + ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall.cancel(); + ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = null; + } + ((PostCard2VideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.GONE); + ((PostCard2VideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); + ((PostCard2VideoAutoplayViewHolder) holder).resetVolume(); + mGlide.clear(((PostCard2VideoAutoplayViewHolder) holder).previewImageView); + ((PostCard2VideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); + } else if (holder instanceof PostCard2WithPreviewViewHolder) { + mGlide.clear(((PostCard2WithPreviewViewHolder) holder).imageView); + ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).errorTextView.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).linkTextView.setVisibility(View.GONE); + } else if (holder instanceof PostCard2TextTypeViewHolder) { + ((PostCard2TextTypeViewHolder) holder).contentTextView.setText(""); + ((PostCard2TextTypeViewHolder) holder).contentTextView.setTextColor(mPostContentColor); + ((PostCard2TextTypeViewHolder) holder).contentTextView.setVisibility(View.GONE); + } + + mGlide.clear(((PostBaseViewHolder) holder).iconGifImageView); + ((PostBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).crosspostImageView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).archivedImageView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).lockedImageView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).nsfwTextView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).spoilerTextView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).flairTextView.setText(""); + ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).awardsTextView.setText(""); + ((PostBaseViewHolder) holder).awardsTextView.setVisibility(View.GONE); + ((PostBaseViewHolder) holder).upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostBaseViewHolder) holder).scoreTextView.setTextColor(mPostIconAndInfoColor); + ((PostBaseViewHolder) holder).downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + } else if (holder instanceof PostCompactBaseViewHolder) { + holder.itemView.setBackgroundColor(mCardViewBackgroundColor); + ((PostCompactBaseViewHolder) holder).titleTextView.setTextColor(mPostTitleColor); + mGlide.clear(((PostCompactBaseViewHolder) holder).imageView); + mGlide.clear(((PostCompactBaseViewHolder) holder).iconGifImageView); + ((PostCompactBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).relativeLayout.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).crosspostImageView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).archivedImageView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).lockedImageView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).nsfwTextView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).spoilerTextView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).flairTextView.setText(""); + ((PostCompactBaseViewHolder) holder).awardsTextView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).awardsTextView.setText(""); + ((PostCompactBaseViewHolder) holder).linkTextView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).imageView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.GONE); + ((PostCompactBaseViewHolder) holder).upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactBaseViewHolder) holder).scoreTextView.setTextColor(mPostIconAndInfoColor); + ((PostCompactBaseViewHolder) holder).downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + } else if (holder instanceof PostGalleryViewHolder) { + holder.itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + + ((PostGalleryViewHolder) holder).titleTextView.setText(""); + ((PostGalleryViewHolder) holder).titleTextView.setVisibility(View.GONE); + mGlide.clear(((PostGalleryViewHolder) holder).imageView); + ((PostGalleryViewHolder) holder).imageView.setVisibility(View.GONE); + ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostGalleryViewHolder) holder).errorTextView.setVisibility(View.GONE); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.GONE); + } + } + + @Nullable + @Override + public Object getKeyForOrder(int order) { + if (super.getItemCount() <= 0 || order >= super.getItemCount()) { + return null; + } + return order; + } + + @Nullable + @Override + public Integer getOrderForKey(@NonNull Object key) { + if (key instanceof Integer) { + return (Integer) key; + } + + return null; + } + + public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) { + if (viewHolder instanceof PostBaseViewHolder) { + if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((PostBaseViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((PostBaseViewHolder) viewHolder).downvoteButton.performClick(); + } + } else { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((PostBaseViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((PostBaseViewHolder) viewHolder).downvoteButton.performClick(); + } + } + } else if (viewHolder instanceof PostCompactBaseViewHolder) { + if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((PostCompactBaseViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((PostCompactBaseViewHolder) viewHolder).downvoteButton.performClick(); + } + } else { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((PostCompactBaseViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((PostCompactBaseViewHolder) viewHolder).downvoteButton.performClick(); + } + } + } + } + + public interface Callback { + void typeChipClicked(int filter); + + void flairChipClicked(String flair); + + void nsfwChipClicked(); + + void currentlyBindItem(int position); + + void delayTransition(); + } + + private void openViewPostDetailActivity(Post post, int position) { + if (canStartActivity) { + canStartActivity = false; + Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, post); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_LIST_POSITION, position); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_FRAGMENT_ID, mFragment.getHistoryPostFragmentId()); + mActivity.startActivity(intent); + } + } + + private void openMedia(Post post) { + if (canStartActivity) { + canStartActivity = false; + if (post.getPostType() == Post.VIDEO_TYPE) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + if (post.isImgur()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR); + } else if (post.isGfycat()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); + } else if (post.isRedgifs()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); + } else if (post.isStreamable()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_STREAMABLE); + intent.putExtra(ViewVideoActivity.EXTRA_STREAMABLE_SHORT_CODE, post.getStreamableShortCode()); + } else { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, post.getSubredditName()); + intent.putExtra(ViewVideoActivity.EXTRA_ID, post.getId()); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + } + intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, post.getTitle()); + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } else if (post.getPostType() == Post.IMAGE_TYPE) { + Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, post.getUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, post.getSubredditName() + + "-" + post.getId() + ".jpg"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, post.getTitle()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, post.getSubredditName()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } else if (post.getPostType() == Post.GIF_TYPE) { + Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, post.getSubredditName() + + "-" + post.getId() + ".gif"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, post.getVideoUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, post.getTitle()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, post.getSubredditName()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(post.getUrl()); + intent.setData(uri); + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class); + intent.putParcelableArrayListExtra(ViewRedditGalleryActivity.EXTRA_REDDIT_GALLERY, post.getGallery()); + intent.putExtra(ViewRedditGalleryActivity.EXTRA_SUBREDDIT_NAME, post.getSubredditName()); + intent.putExtra(ViewRedditGalleryActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } + } + } + + public void setCanPlayVideo(boolean canPlayVideo) { + this.canPlayVideo = canPlayVideo; + } + + public class PostBaseViewHolder extends RecyclerView.ViewHolder { + AspectRatioGifImageView iconGifImageView; + TextView subredditTextView; + TextView userTextView; + ImageView stickiedPostImageView; + TextView postTimeTextView; + TextView titleTextView; + CustomTextView typeTextView; + ImageView archivedImageView; + ImageView lockedImageView; + ImageView crosspostImageView; + CustomTextView nsfwTextView; + CustomTextView spoilerTextView; + CustomTextView flairTextView; + CustomTextView awardsTextView; + ConstraintLayout bottomConstraintLayout; + ImageView upvoteButton; + TextView scoreTextView; + ImageView downvoteButton; + TextView commentsCountTextView; + ImageView saveButton; + ImageView shareButton; + Post post; + Post.Preview preview; + + boolean itemViewIsNotCardView = false; + + PostBaseViewHolder(@NonNull View itemView) { + super(itemView); + } + + void setBaseView(AspectRatioGifImageView iconGifImageView, + TextView subredditTextView, + TextView userTextView, + ImageView stickiedPostImageView, + TextView postTimeTextView, + TextView titleTextView, + CustomTextView typeTextView, + ImageView archivedImageView, + ImageView lockedImageView, + ImageView crosspostImageView, + CustomTextView nsfwTextView, + CustomTextView spoilerTextView, + CustomTextView flairTextView, + CustomTextView awardsTextView, + ConstraintLayout bottomConstraintLayout, + ImageView upvoteButton, + TextView scoreTextView, + ImageView downvoteButton, + TextView commentsCountTextView, + ImageView saveButton, + ImageView shareButton) { + this.iconGifImageView = iconGifImageView; + this.subredditTextView = subredditTextView; + this.userTextView = userTextView; + this.stickiedPostImageView = stickiedPostImageView; + this.postTimeTextView = postTimeTextView; + this.titleTextView = titleTextView; + this.typeTextView = typeTextView; + this.archivedImageView = archivedImageView; + this.lockedImageView = lockedImageView; + this.crosspostImageView = crosspostImageView; + this.nsfwTextView = nsfwTextView; + this.spoilerTextView = spoilerTextView; + this.flairTextView = flairTextView; + this.awardsTextView = awardsTextView; + this.bottomConstraintLayout = bottomConstraintLayout; + this.upvoteButton = upvoteButton; + this.scoreTextView = scoreTextView; + this.downvoteButton = downvoteButton; + this.commentsCountTextView = commentsCountTextView; + this.saveButton = saveButton; + this.shareButton = shareButton; + + scoreTextView.setOnClickListener(null); + + 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); + } + + if (itemViewIsNotCardView) { + itemView.setBackgroundColor(mCardViewBackgroundColor); + } else { + itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + } + + if (mActivity.typeface != null) { + subredditTextView.setTypeface(mActivity.typeface); + userTextView.setTypeface(mActivity.typeface); + postTimeTextView.setTypeface(mActivity.typeface); + typeTextView.setTypeface(mActivity.typeface); + spoilerTextView.setTypeface(mActivity.typeface); + nsfwTextView.setTypeface(mActivity.typeface); + flairTextView.setTypeface(mActivity.typeface); + awardsTextView.setTypeface(mActivity.typeface); + scoreTextView.setTypeface(mActivity.typeface); + commentsCountTextView.setTypeface(mActivity.typeface); + } + if (mActivity.titleTypeface != null) { + titleTextView.setTypeface(mActivity.titleTypeface); + } + + subredditTextView.setTextColor(mSubredditColor); + userTextView.setTextColor(mUsernameColor); + postTimeTextView.setTextColor(mSecondaryTextColor); + titleTextView.setTextColor(mPostTitleColor); + stickiedPostImageView.setColorFilter(mStickiedPostIconTint, PorterDuff.Mode.SRC_IN); + typeTextView.setBackgroundColor(mPostTypeBackgroundColor); + typeTextView.setBorderColor(mPostTypeBackgroundColor); + typeTextView.setTextColor(mPostTypeTextColor); + spoilerTextView.setBackgroundColor(mSpoilerBackgroundColor); + spoilerTextView.setBorderColor(mSpoilerBackgroundColor); + spoilerTextView.setTextColor(mSpoilerTextColor); + nsfwTextView.setBackgroundColor(mNSFWBackgroundColor); + nsfwTextView.setBorderColor(mNSFWBackgroundColor); + nsfwTextView.setTextColor(mNSFWTextColor); + flairTextView.setBackgroundColor(mFlairBackgroundColor); + flairTextView.setBorderColor(mFlairBackgroundColor); + flairTextView.setTextColor(mFlairTextColor); + awardsTextView.setBackgroundColor(mAwardsBackgroundColor); + awardsTextView.setBorderColor(mAwardsBackgroundColor); + awardsTextView.setTextColor(mAwardsTextColor); + archivedImageView.setColorFilter(mArchivedIconTint, PorterDuff.Mode.SRC_IN); + lockedImageView.setColorFilter(mLockedIconTint, PorterDuff.Mode.SRC_IN); + crosspostImageView.setColorFilter(mCrosspostIconTint, PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + commentsCountTextView.setTextColor(mPostIconAndInfoColor); + commentsCountTextView.setCompoundDrawablesWithIntrinsicBounds(mCommentIcon, null, null, null); + saveButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + shareButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + itemView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position >= 0 && canStartActivity) { + Post post = getItem(position); + if (post != null) { + openViewPostDetailActivity(post, getBindingAdapterPosition()); + } + } + }); + + userTextView.setOnClickListener(view -> { + if (canStartActivity) { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + canStartActivity = false; + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); + mActivity.startActivity(intent); + } + } + }); + + if (mDisplaySubredditName) { + subredditTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (canStartActivity) { + canStartActivity = false; + Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, + post.getSubredditName()); + mActivity.startActivity(intent); + } + } + }); + + iconGifImageView.setOnClickListener(view -> subredditTextView.performClick()); + } else { + subredditTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (canStartActivity) { + canStartActivity = false; + Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, + post.getSubredditName()); + mActivity.startActivity(intent); + } + } + }); + + iconGifImageView.setOnClickListener(view -> userTextView.performClick()); + } + + if (!(mActivity instanceof FilteredPostsActivity)) { + nsfwTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + mCallback.nsfwChipClicked(); + } + }); + typeTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + mCallback.typeChipClicked(post.getPostType()); + } + }); + + flairTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + mCallback.flairChipClicked(post.getFlair()); + } + }); + } + + upvoteButton.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != 1) { + //Not upvoted before + post.setVoteType(1); + newVoteType = APIUtils.DIR_UPVOTE; + upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + post.setVoteType(1); + if (currentPosition == position) { + upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } + } else { + post.setVoteType(0); + if (currentPosition == position) { + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + } + + if (currentPosition == position) { + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + if (getBindingAdapterPosition() == position) { + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + } + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }, post.getFullName(), newVoteType, getBindingAdapterPosition()); + } + }); + + downvoteButton.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != -1) { + //Not downvoted before + post.setVoteType(-1); + newVoteType = APIUtils.DIR_DOWNVOTE; + downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + post.setVoteType(-1); + if (currentPosition == position) { + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } + } else { + post.setVoteType(0); + if (currentPosition == position) { + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + } + + if (currentPosition == position) { + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + if (getBindingAdapterPosition() == position) { + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + } + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }, post.getFullName(), newVoteType, getBindingAdapterPosition()); + } + }); + + saveButton.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (post.isSaved()) { + 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); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void failed() { + post.setSaved(true); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }); + } else { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(true); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void failed() { + post.setSaved(false); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_saved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }); + } + } + }); + + shareButton.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + shareLink(post); + } + }); + } + + void setBaseView(AspectRatioGifImageView iconGifImageView, + TextView subredditTextView, + TextView userTextView, + ImageView stickiedPostImageView, + TextView postTimeTextView, + TextView titleTextView, + CustomTextView typeTextView, + ImageView archivedImageView, + ImageView lockedImageView, + ImageView crosspostImageView, + CustomTextView nsfwTextView, + CustomTextView spoilerTextView, + CustomTextView flairTextView, + CustomTextView awardsTextView, + ConstraintLayout bottomConstraintLayout, + ImageView upvoteButton, + TextView scoreTextView, + ImageView downvoteButton, + TextView commentsCountTextView, + ImageView saveButton, + ImageView shareButton, boolean itemViewIsNotCardView) { + this.itemViewIsNotCardView = itemViewIsNotCardView; + + setBaseView(iconGifImageView, subredditTextView, userTextView, stickiedPostImageView, postTimeTextView, + titleTextView, typeTextView, archivedImageView, lockedImageView, crosspostImageView, + nsfwTextView, spoilerTextView, flairTextView, awardsTextView, bottomConstraintLayout, + upvoteButton, scoreTextView, downvoteButton, commentsCountTextView, saveButton, shareButton); + } + } + + class PostVideoAutoplayViewHolder extends PostBaseViewHolder implements ToroPlayer { + @BindView(R.id.icon_gif_image_view_item_post_video_type_autoplay) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_post_video_type_autoplay) + TextView subredditTextView; + @BindView(R.id.user_text_view_item_post_video_type_autoplay) + TextView userTextView; + @BindView(R.id.stickied_post_image_view_item_post_video_type_autoplay) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_video_type_autoplay) + TextView postTimeTextView; + @BindView(R.id.title_text_view_item_post_video_type_autoplay) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_video_type_autoplay) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_video_type_autoplay) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_video_type_autoplay) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_video_type_autoplay) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_video_type_autoplay) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_video_type_autoplay) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_video_type_autoplay) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_video_type_autoplay) + CustomTextView awardsTextView; + @BindView(R.id.aspect_ratio_frame_layout_item_post_video_type_autoplay) + AspectRatioFrameLayout aspectRatioFrameLayout; + @BindView(R.id.preview_image_view_item_post_video_type_autoplay) + GifImageView previewImageView; + @BindView(R.id.error_loading_gfycat_image_view_item_post_video_type_autoplay) + ImageView errorLoadingGfycatImageView; + @BindView(R.id.player_view_item_post_video_type_autoplay) + PlayerView videoPlayer; + @BindView(R.id.mute_exo_playback_control_view) + ImageView muteButton; + @BindView(R.id.fullscreen_exo_playback_control_view) + ImageView fullscreenButton; + @BindView(R.id.bottom_constraint_layout_item_post_video_type_autoplay) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_video_type_autoplay) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_video_type_autoplay) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_video_type_autoplay) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_video_type_autoplay) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_video_type_autoplay) + ImageView saveButton; + @BindView(R.id.share_button_item_post_video_type_autoplay) + ImageView shareButton; + + @Nullable + ExoPlayerViewHelper helper; + private Uri mediaUri; + private float volume; + public Call<String> fetchGfycatOrStreamableVideoCall; + + PostVideoAutoplayViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView( + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton); + + aspectRatioFrameLayout.setOnClickListener(null); + + muteButton.setOnClickListener(view -> { + if (helper != null) { + if (helper.getVolume() != 0) { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); + helper.setVolume(0f); + volume = 0f; + mFragment.videoAutoplayChangeMutingOption(true); + } else { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); + helper.setVolume(1f); + volume = 1f; + mFragment.videoAutoplayChangeMutingOption(false); + } + } + }); + + fullscreenButton.setOnClickListener(view -> { + if (canStartActivity) { + canStartActivity = false; + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + if (post.isImgur()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR); + } else if (post.isGfycat()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); + if (post.isLoadGfycatOrStreamableVideoSuccess()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + } + } else if (post.isRedgifs()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); + if (post.isLoadGfycatOrStreamableVideoSuccess()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + } + } else if (post.isStreamable()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_STREAMABLE); + intent.putExtra(ViewVideoActivity.EXTRA_STREAMABLE_SHORT_CODE, post.getStreamableShortCode()); + } else { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, post.getSubredditName()); + intent.putExtra(ViewVideoActivity.EXTRA_ID, post.getId()); + } + intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, post.getTitle()); + if (helper != null) { + intent.putExtra(ViewVideoActivity.EXTRA_PROGRESS_SECONDS, helper.getLatestPlaybackInfo().getResumePosition()); + } + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } + } + }); + + previewImageView.setOnClickListener(view -> fullscreenButton.performClick()); + + videoPlayer.setOnClickListener(view -> { + if (mEasierToWatchInFullScreen && videoPlayer.isControllerVisible()) { + fullscreenButton.performClick(); + } + }); + } + + void bindVideoUri(Uri videoUri) { + mediaUri = videoUri; + } + + void setVolume(float volume) { + this.volume = volume; + } + + void resetVolume() { + volume = 0f; + } + + @NonNull + @Override + public View getPlayerView() { + return videoPlayer; + } + + @NonNull + @Override + public PlaybackInfo getCurrentPlaybackInfo() { + return helper != null && mediaUri != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo(); + } + + @Override + public void initialize(@NonNull Container container, @NonNull PlaybackInfo playbackInfo) { + if (mediaUri == null) { + return; + } + if (helper == null) { + helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); + helper.addEventListener(new Playable.DefaultEventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + if (mFragment.getMasterMutingOption() != null) { + volume = mFragment.getMasterMutingOption() ? 0f : 1f; + } + helper.setVolume(volume); + muteButton.setVisibility(View.VISIBLE); + if (volume != 0f) { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); + } else { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); + } + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + + @Override + public void onRenderedFirstFrame() { + mGlide.clear(previewImageView); + previewImageView.setVisibility(View.GONE); + } + }); + } + helper.initialize(container, playbackInfo); + } + + @Override + public void play() { + if (helper != null && mediaUri != null) { + helper.play(); + } + } + + @Override + public void pause() { + if (helper != null) helper.pause(); + } + + @Override + public boolean isPlaying() { + return helper != null && helper.isPlaying(); + } + + @Override + public void release() { + if (helper != null) { + helper.release(); + helper = null; + } + } + + @Override + public boolean wantsToPlay() { + return canPlayVideo && mediaUri != null && ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= mStartAutoplayVisibleAreaOffset; + } + + @Override + public int getPlayerOrder() { + return getBindingAdapterPosition(); + } + } + + class PostWithPreviewTypeViewHolder extends PostBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_with_preview) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_post_with_preview) + TextView subredditTextView; + @BindView(R.id.user_text_view_item_post_with_preview) + TextView userTextView; + @BindView(R.id.stickied_post_image_view_item_post_with_preview) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_with_preview) + TextView postTimeTextView; + @BindView(R.id.title_text_view_item_post_with_preview) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_with_preview) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_with_preview) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_with_preview) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_with_preview) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_with_preview) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_with_preview) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_with_preview) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_with_preview) + CustomTextView awardsTextView; + @BindView(R.id.link_text_view_item_post_with_preview) + TextView linkTextView; + @BindView(R.id.video_or_gif_indicator_image_view_item_post_with_preview) + ImageView videoOrGifIndicatorImageView; + @BindView(R.id.image_wrapper_relative_layout_item_post_with_preview) + FrameLayout imageWrapperRelativeLayout; + @BindView(R.id.progress_bar_item_post_with_preview) + ProgressBar progressBar; + @BindView(R.id.image_view_item_post_with_preview) + AspectRatioGifImageView imageView; + @BindView(R.id.load_image_error_text_view_item_post_with_preview) + TextView errorTextView; + @BindView(R.id.image_view_no_preview_gallery_item_post_with_preview) + ImageView noPreviewLinkImageView; + @BindView(R.id.bottom_constraint_layout_item_post_with_preview) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_with_preview) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_with_preview) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_with_preview) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_with_preview) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_with_preview) + ImageView saveButton; + @BindView(R.id.share_button_item_post_with_preview) + ImageView shareButton; + RequestListener<Drawable> glideRequestListener; + + PostWithPreviewTypeViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView( + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton); + + if (mActivity.typeface != null) { + linkTextView.setTypeface(mActivity.typeface); + errorTextView.setTypeface(mActivity.typeface); + } + linkTextView.setTextColor(mSecondaryTextColor); + noPreviewLinkImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + noPreviewLinkImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + videoOrGifIndicatorImageView.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN); + videoOrGifIndicatorImageView.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); + errorTextView.setTextColor(mPrimaryTextColor); + + imageView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + openMedia(post); + } + }); + + errorTextView.setOnClickListener(view -> { + progressBar.setVisibility(View.VISIBLE); + errorTextView.setVisibility(View.GONE); + loadImage(this); + }); + + noPreviewLinkImageView.setOnClickListener(view -> { + imageView.performClick(); + }); + + glideRequestListener = new RequestListener<>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + errorTextView.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + errorTextView.setVisibility(View.GONE); + progressBar.setVisibility(View.GONE); + return false; + } + }; + } + } + + class PostTextTypeViewHolder extends PostBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_text_type) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_post_text_type) + TextView subredditTextView; + @BindView(R.id.user_text_view_item_post_text_type) + TextView userTextView; + @BindView(R.id.stickied_post_image_view_item_post_text_type) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_text_type) + TextView postTimeTextView; + @BindView(R.id.title_text_view_item_post_text_type) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_text_type) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_text_type) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_text_type) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_text_type) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_text_type) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_text_type) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_text_type) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_text_type) + CustomTextView awardsTextView; + @BindView(R.id.content_text_view_item_post_text_type) + TextView contentTextView; + @BindView(R.id.bottom_constraint_layout_item_post_text_type) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_text_type) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_text_type) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_text_type) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_text_type) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_text_type) + ImageView saveButton; + @BindView(R.id.share_button_item_post_text_type) + ImageView shareButton; + + PostTextTypeViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView( + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton); + + if (mActivity.contentTypeface != null) { + contentTextView.setTypeface(mActivity.titleTypeface); + } + contentTextView.setTextColor(mPostContentColor); + } + } + + public class PostCompactBaseViewHolder extends RecyclerView.ViewHolder { + AspectRatioGifImageView iconGifImageView; + TextView nameTextView; + ImageView stickiedPostImageView; + TextView postTimeTextView; + ConstraintLayout titleAndImageConstraintLayout; + TextView titleTextView; + CustomTextView typeTextView; + ImageView archivedImageView; + ImageView lockedImageView; + ImageView crosspostImageView; + CustomTextView nsfwTextView; + CustomTextView spoilerTextView; + CustomTextView flairTextView; + CustomTextView awardsTextView; + TextView linkTextView; + RelativeLayout relativeLayout; + ProgressBar progressBar; + ImageView imageView; + ImageView playButtonImageView; + FrameLayout noPreviewPostImageFrameLayout; + ImageView noPreviewPostImageView; + Barrier imageBarrier; + ConstraintLayout bottomConstraintLayout; + ImageView upvoteButton; + TextView scoreTextView; + ImageView downvoteButton; + TextView commentsCountTextView; + ImageView saveButton; + ImageView shareButton; + View divider; + RequestListener<Drawable> requestListener; + Post post; + + PostCompactBaseViewHolder(View itemView) { + super(itemView); + } + + void setBaseView(AspectRatioGifImageView iconGifImageView, + TextView nameTextView, ImageView stickiedPostImageView, + TextView postTimeTextView, ConstraintLayout titleAndImageConstraintLayout, + TextView titleTextView, CustomTextView typeTextView, + ImageView archivedImageView, ImageView lockedImageView, + ImageView crosspostImageView, CustomTextView nsfwTextView, + CustomTextView spoilerTextView, CustomTextView flairTextView, + CustomTextView awardsTextView, TextView linkTextView, + RelativeLayout relativeLayout, ProgressBar progressBar, + ImageView imageView, ImageView playButtonImageView, + FrameLayout noPreviewLinkImageFrameLayout, + ImageView noPreviewLinkImageView, Barrier imageBarrier, + ConstraintLayout bottomConstraintLayout, ImageView upvoteButton, + TextView scoreTextView, ImageView downvoteButton, + TextView commentsCountTextView, ImageView saveButton, + ImageView shareButton, View divider) { + this.iconGifImageView = iconGifImageView; + this.nameTextView = nameTextView; + this.stickiedPostImageView = stickiedPostImageView; + this.postTimeTextView = postTimeTextView; + this.titleAndImageConstraintLayout = titleAndImageConstraintLayout; + this.titleTextView = titleTextView; + this.typeTextView = typeTextView; + this.archivedImageView = archivedImageView; + this.lockedImageView = lockedImageView; + this.crosspostImageView = crosspostImageView; + this.nsfwTextView = nsfwTextView; + this.spoilerTextView = spoilerTextView; + this.flairTextView = flairTextView; + this.awardsTextView = awardsTextView; + this.linkTextView = linkTextView; + this.relativeLayout = relativeLayout; + this.progressBar = progressBar; + this.imageView = imageView; + this.playButtonImageView = playButtonImageView; + this.noPreviewPostImageFrameLayout = noPreviewLinkImageFrameLayout; + this.noPreviewPostImageView = noPreviewLinkImageView; + this.imageBarrier = imageBarrier; + this.bottomConstraintLayout = bottomConstraintLayout; + this.upvoteButton = upvoteButton; + this.scoreTextView = scoreTextView; + this.downvoteButton = downvoteButton; + this.commentsCountTextView = commentsCountTextView; + this.saveButton = saveButton; + this.shareButton = shareButton; + this.divider = divider; + + scoreTextView.setOnClickListener(null); + + 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); + } + + if (((ViewGroup) itemView).getLayoutTransition() != null) { + ((ViewGroup) itemView).getLayoutTransition().setAnimateParentHierarchy(false); + } + + if (mActivity.typeface != null) { + nameTextView.setTypeface(mActivity.typeface); + postTimeTextView.setTypeface(mActivity.typeface); + typeTextView.setTypeface(mActivity.typeface); + spoilerTextView.setTypeface(mActivity.typeface); + nsfwTextView.setTypeface(mActivity.typeface); + flairTextView.setTypeface(mActivity.typeface); + awardsTextView.setTypeface(mActivity.typeface); + linkTextView.setTypeface(mActivity.typeface); + scoreTextView.setTypeface(mActivity.typeface); + commentsCountTextView.setTypeface(mActivity.typeface); + } + if (mActivity.titleTypeface != null) { + titleTextView.setTypeface(mActivity.titleTypeface); + } + + itemView.setBackgroundColor(mCardViewBackgroundColor); + postTimeTextView.setTextColor(mSecondaryTextColor); + titleTextView.setTextColor(mPostTitleColor); + stickiedPostImageView.setColorFilter(mStickiedPostIconTint, PorterDuff.Mode.SRC_IN); + typeTextView.setBackgroundColor(mPostTypeBackgroundColor); + typeTextView.setBorderColor(mPostTypeBackgroundColor); + typeTextView.setTextColor(mPostTypeTextColor); + spoilerTextView.setBackgroundColor(mSpoilerBackgroundColor); + spoilerTextView.setBorderColor(mSpoilerBackgroundColor); + spoilerTextView.setTextColor(mSpoilerTextColor); + nsfwTextView.setBackgroundColor(mNSFWBackgroundColor); + nsfwTextView.setBorderColor(mNSFWBackgroundColor); + nsfwTextView.setTextColor(mNSFWTextColor); + flairTextView.setBackgroundColor(mFlairBackgroundColor); + flairTextView.setBorderColor(mFlairBackgroundColor); + flairTextView.setTextColor(mFlairTextColor); + awardsTextView.setBackgroundColor(mAwardsBackgroundColor); + awardsTextView.setBorderColor(mAwardsBackgroundColor); + awardsTextView.setTextColor(mAwardsTextColor); + archivedImageView.setColorFilter(mArchivedIconTint, PorterDuff.Mode.SRC_IN); + lockedImageView.setColorFilter(mLockedIconTint, PorterDuff.Mode.SRC_IN); + crosspostImageView.setColorFilter(mCrosspostIconTint, PorterDuff.Mode.SRC_IN); + linkTextView.setTextColor(mSecondaryTextColor); + playButtonImageView.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN); + playButtonImageView.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + noPreviewLinkImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + noPreviewLinkImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + commentsCountTextView.setTextColor(mPostIconAndInfoColor); + commentsCountTextView.setCompoundDrawablesWithIntrinsicBounds(mCommentIcon, null, null, null); + saveButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + shareButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + divider.setBackgroundColor(mDividerColor); + + imageView.setClipToOutline(true); + noPreviewLinkImageFrameLayout.setClipToOutline(true); + + itemView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && canStartActivity) { + openViewPostDetailActivity(post, getBindingAdapterPosition()); + } + }); + + itemView.setOnLongClickListener(view -> { + if (mLongPressToHideToolbarInCompactLayout) { + if (bottomConstraintLayout.getLayoutParams().height == 0) { + ViewGroup.LayoutParams params = bottomConstraintLayout.getLayoutParams(); + params.height = LinearLayout.LayoutParams.WRAP_CONTENT; + bottomConstraintLayout.setLayoutParams(params); + mCallback.delayTransition(); + } else { + mCallback.delayTransition(); + ViewGroup.LayoutParams params = bottomConstraintLayout.getLayoutParams(); + params.height = 0; + bottomConstraintLayout.setLayoutParams(params); + } + } + return true; + }); + + nameTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && canStartActivity) { + canStartActivity = false; + if (mDisplaySubredditName) { + Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, + post.getSubredditName()); + mActivity.startActivity(intent); + } else { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); + mActivity.startActivity(intent); + } + } + }); + + iconGifImageView.setOnClickListener(view -> nameTextView.performClick()); + + nsfwTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && !(mActivity instanceof FilteredPostsActivity)) { + mCallback.nsfwChipClicked(); + } + }); + + typeTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && !(mActivity instanceof FilteredPostsActivity)) { + mCallback.typeChipClicked(post.getPostType()); + } + }); + + flairTextView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && !(mActivity instanceof FilteredPostsActivity)) { + mCallback.flairChipClicked(post.getFlair()); + } + }); + + imageView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + openMedia(post); + } + }); + + noPreviewLinkImageFrameLayout.setOnClickListener(view -> { + imageView.performClick(); + }); + + upvoteButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != 1) { + //Not upvoted before + post.setVoteType(1); + newVoteType = APIUtils.DIR_UPVOTE; + upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + post.setVoteType(1); + if (currentPosition == position) { + upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } + } else { + post.setVoteType(0); + if (currentPosition == position) { + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + } + + if (currentPosition == position) { + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + if (getBindingAdapterPosition() == position) { + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + } + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }, post.getFullName(), newVoteType, getBindingAdapterPosition()); + } + }); + + downvoteButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != -1) { + //Not downvoted before + post.setVoteType(-1); + newVoteType = APIUtils.DIR_DOWNVOTE; + downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + post.setVoteType(-1); + if (currentPosition == position) { + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } + + } else { + post.setVoteType(0); + if (currentPosition == position) { + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + } + + if (currentPosition == position) { + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + if (getBindingAdapterPosition() == position) { + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + } + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }, post.getFullName(), newVoteType, getBindingAdapterPosition()); + } + }); + + saveButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.isSaved()) { + 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); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void failed() { + post.setSaved(true); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }); + } else { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(true); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + + @Override + public void failed() { + post.setSaved(false); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + Toast.makeText(mActivity, R.string.post_saved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }); + } + } + }); + + shareButton.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + shareLink(post); + } + }); + + requestListener = new RequestListener<>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + return false; + } + }; + } + } + + class PostCompactLeftThumbnailViewHolder extends PostCompactBaseViewHolder { + @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_item_post_compact) + TextView postTimeTextView; + @BindView(R.id.title_and_image_constraint_layout) + ConstraintLayout titleAndImageConstraintLayout; + @BindView(R.id.title_text_view_item_post_compact) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_compact) + CustomTextView typeTextView; + @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.awards_text_view_item_post_compact) + CustomTextView awardsTextView; + @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_item_post_compact) + ImageView imageView; + @BindView(R.id.play_button_image_view_item_post_compact) + ImageView playButtonImageView; + @BindView(R.id.frame_layout_image_view_no_preview_link_item_post_compact) + FrameLayout noPreviewLinkImageFrameLayout; + @BindView(R.id.image_view_no_preview_link_item_post_compact) + ImageView noPreviewLinkImageView; + @BindView(R.id.barrier2) + Barrier imageBarrier; + @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; + @BindView(R.id.divider_item_post_compact) + View divider; + + PostCompactLeftThumbnailViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + setBaseView(iconGifImageView, nameTextView, stickiedPostImageView, postTimeTextView, + titleAndImageConstraintLayout, titleTextView, typeTextView, archivedImageView, + lockedImageView, crosspostImageView, nsfwTextView, spoilerTextView, + flairTextView, awardsTextView, linkTextView, relativeLayout, progressBar, imageView, + playButtonImageView, noPreviewLinkImageFrameLayout, noPreviewLinkImageView, + imageBarrier, bottomConstraintLayout, upvoteButton, scoreTextView, downvoteButton, + commentsCountTextView, saveButton, shareButton, divider); + } + } + + class PostCompactRightThumbnailViewHolder extends PostCompactBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_compact_right_thumbnail) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.name_text_view_item_post_compact_right_thumbnail) + TextView nameTextView; + @BindView(R.id.stickied_post_image_view_item_post_compact_right_thumbnail) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_compact_right_thumbnail) + TextView postTimeTextView; + @BindView(R.id.title_and_image_constraint_layout) + ConstraintLayout titleAndImageConstraintLayout; + @BindView(R.id.title_text_view_item_post_compact_right_thumbnail) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_compact_right_thumbnail) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_compact_right_thumbnail) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_compact_right_thumbnail) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_compact_right_thumbnail) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_compact_right_thumbnail) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_compact_right_thumbnail) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_compact_right_thumbnail) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_compact_right_thumbnail) + CustomTextView awardsTextView; + @BindView(R.id.link_text_view_item_post_compact_right_thumbnail) + TextView linkTextView; + @BindView(R.id.image_view_wrapper_item_post_compact_right_thumbnail) + RelativeLayout relativeLayout; + @BindView(R.id.progress_bar_item_post_compact_right_thumbnail) + ProgressBar progressBar; + @BindView(R.id.image_view_item_post_compact_right_thumbnail) + ImageView imageView; + @BindView(R.id.play_button_image_view_item_post_compact_right_thumbnail) + ImageView playButtonImageView; + @BindView(R.id.frame_layout_image_view_no_preview_link_item_post_compact_right_thumbnail) + FrameLayout noPreviewLinkImageFrameLayout; + @BindView(R.id.image_view_no_preview_link_item_post_compact_right_thumbnail) + ImageView noPreviewLinkImageView; + @BindView(R.id.barrier2) + Barrier imageBarrier; + @BindView(R.id.bottom_constraint_layout_item_post_compact_right_thumbnail) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_compact_right_thumbnail) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_compact_right_thumbnail) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_compact_right_thumbnail) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_compact_right_thumbnail) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_compact_right_thumbnail) + ImageView saveButton; + @BindView(R.id.share_button_item_post_compact_right_thumbnail) + ImageView shareButton; + @BindView(R.id.divider_item_post_compact_right_thumbnail) + View divider; + + PostCompactRightThumbnailViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + setBaseView(iconGifImageView, nameTextView, stickiedPostImageView, postTimeTextView, + titleAndImageConstraintLayout, titleTextView, typeTextView, archivedImageView, + lockedImageView, crosspostImageView, nsfwTextView, spoilerTextView, + flairTextView, awardsTextView, linkTextView, relativeLayout, progressBar, imageView, + playButtonImageView, noPreviewLinkImageFrameLayout, noPreviewLinkImageView, + imageBarrier, bottomConstraintLayout, upvoteButton, scoreTextView, downvoteButton, + commentsCountTextView, saveButton, shareButton, divider); + } + } + + class PostGalleryViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_post_gallery) + ProgressBar progressBar; + @BindView(R.id.video_or_gif_indicator_image_view_item_post_gallery) + ImageView videoOrGifIndicatorImageView; + @BindView(R.id.image_view_item_post_gallery) + AspectRatioGifImageView imageView; + @BindView(R.id.load_image_error_text_view_item_gallery) + TextView errorTextView; + @BindView(R.id.image_view_no_preview_item_post_gallery) + ImageView noPreviewImageView; + @BindView(R.id.title_text_view_item_post_gallery) + TextView titleTextView; + RequestListener<Drawable> requestListener; + Post post; + Post.Preview preview; + + public PostGalleryViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + if (mActivity.typeface != null) { + errorTextView.setTypeface(mActivity.typeface); + } + if (mActivity.titleTypeface != null) { + titleTextView.setTypeface(mActivity.titleTypeface); + } + itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + titleTextView.setTextColor(mPostTitleColor); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + noPreviewImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + noPreviewImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + videoOrGifIndicatorImageView.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN); + videoOrGifIndicatorImageView.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); + errorTextView.setTextColor(mPrimaryTextColor); + + itemView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position >= 0 && canStartActivity) { + Post post = getItem(position); + if (post != null) { + if (post.getPostType() == Post.TEXT_TYPE || !mSharedPreferences.getBoolean(SharedPreferencesUtils.CLICK_TO_SHOW_MEDIA_IN_GALLERY_LAYOUT, false)) { + openViewPostDetailActivity(post, getBindingAdapterPosition()); + } else { + openMedia(post); + } + } + } + }); + + itemView.setOnLongClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position >= 0 && canStartActivity) { + Post post = getItem(position); + if (post != null) { + if (post.getPostType() == Post.TEXT_TYPE || mSharedPreferences.getBoolean(SharedPreferencesUtils.CLICK_TO_SHOW_MEDIA_IN_GALLERY_LAYOUT, false)) { + openViewPostDetailActivity(post, getBindingAdapterPosition()); + } else { + openMedia(post); + } + } + } + + return true; + }); + + errorTextView.setOnClickListener(view -> { + progressBar.setVisibility(View.VISIBLE); + errorTextView.setVisibility(View.GONE); + loadImage(this); + }); + + noPreviewImageView.setOnClickListener(view -> { + itemView.performClick(); + }); + + requestListener = new RequestListener<>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + errorTextView.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + errorTextView.setVisibility(View.GONE); + progressBar.setVisibility(View.GONE); + return false; + } + }; + } + } + + class PostCard2VideoAutoplayViewHolder extends PostBaseViewHolder implements ToroPlayer { + @BindView(R.id.icon_gif_image_view_item_post_card_2_video_autoplay) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_post_card_2_video_autoplay) + TextView subredditTextView; + @BindView(R.id.user_text_view_item_post_card_2_video_autoplay) + TextView userTextView; + @BindView(R.id.stickied_post_image_view_item_post_card_2_video_autoplay) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_card_2_video_autoplay) + TextView postTimeTextView; + @BindView(R.id.title_text_view_item_post_card_2_video_autoplay) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_card_2_video_autoplay) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_card_2_video_autoplay) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_card_2_video_autoplay) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_card_2_video_autoplay) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_card_2_video_autoplay) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_card_2_video_autoplay) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_card_2_video_autoplay) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_card_2_video_autoplay) + CustomTextView awardsTextView; + @BindView(R.id.aspect_ratio_frame_layout_item_post_card_2_video_autoplay) + AspectRatioFrameLayout aspectRatioFrameLayout; + @BindView(R.id.preview_image_view_item_post_card_2_video_autoplay) + GifImageView previewImageView; + @BindView(R.id.error_loading_gfycat_image_view_item_post_card_2_video_autoplay) + ImageView errorLoadingGfycatImageView; + @BindView(R.id.player_view_item_post_card_2_video_autoplay) + PlayerView videoPlayer; + @BindView(R.id.mute_exo_playback_control_view) + ImageView muteButton; + @BindView(R.id.fullscreen_exo_playback_control_view) + ImageView fullscreenButton; + @BindView(R.id.bottom_constraint_layout_item_post_card_2_video_autoplay) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_card_2_video_autoplay) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_card_2_video_autoplay) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_card_2_video_autoplay) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_card_2_video_autoplay) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_card_2_video_autoplay) + ImageView saveButton; + @BindView(R.id.share_button_item_post_card_2_video_autoplay) + ImageView shareButton; + @BindView(R.id.divider_item_post_card_2_video_autoplay) + View divider; + + @Nullable + ExoPlayerViewHelper helper; + private Uri mediaUri; + private float volume; + public Call<String> fetchGfycatOrStreamableVideoCall; + + PostCard2VideoAutoplayViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView( + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton, + true); + + divider.setBackgroundColor(mDividerColor); + + aspectRatioFrameLayout.setOnClickListener(null); + + muteButton.setOnClickListener(view -> { + if (helper != null) { + if (helper.getVolume() != 0) { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); + helper.setVolume(0f); + volume = 0f; + mFragment.videoAutoplayChangeMutingOption(true); + } else { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); + helper.setVolume(1f); + volume = 1f; + mFragment.videoAutoplayChangeMutingOption(false); + } + } + }); + + fullscreenButton.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + if (post.isImgur()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR); + } else if (post.isGfycat()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); + if (post.isLoadGfycatOrStreamableVideoSuccess()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + } + } else if (post.isRedgifs()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); + if (post.isLoadGfycatOrStreamableVideoSuccess()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + } + } else if (post.isStreamable()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_STREAMABLE); + intent.putExtra(ViewVideoActivity.EXTRA_STREAMABLE_SHORT_CODE, post.getStreamableShortCode()); + } else { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, post.getSubredditName()); + intent.putExtra(ViewVideoActivity.EXTRA_ID, post.getId()); + } + intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, post.getTitle()); + if (helper != null) { + intent.putExtra(ViewVideoActivity.EXTRA_PROGRESS_SECONDS, helper.getLatestPlaybackInfo().getResumePosition()); + } + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } + }); + + previewImageView.setOnClickListener(view -> fullscreenButton.performClick()); + + videoPlayer.setOnClickListener(view -> { + if (mEasierToWatchInFullScreen && videoPlayer.isControllerVisible()) { + fullscreenButton.performClick(); + } + }); + } + + void bindVideoUri(Uri videoUri) { + mediaUri = videoUri; + } + + void setVolume(float volume) { + this.volume = volume; + } + + void resetVolume() { + volume = 0f; + } + + @NonNull + @Override + public View getPlayerView() { + return videoPlayer; + } + + @NonNull + @Override + public PlaybackInfo getCurrentPlaybackInfo() { + return helper != null && mediaUri != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo(); + } + + @Override + public void initialize(@NonNull Container container, @NonNull PlaybackInfo playbackInfo) { + if (mediaUri == null) { + return; + } + if (helper == null) { + helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); + helper.addEventListener(new Playable.DefaultEventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + if (mFragment.getMasterMutingOption() != null) { + volume = mFragment.getMasterMutingOption() ? 0f : 1f; + } + helper.setVolume(volume); + muteButton.setVisibility(View.VISIBLE); + if (volume != 0f) { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); + } else { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); + } + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + + @Override + public void onRenderedFirstFrame() { + mGlide.clear(previewImageView); + previewImageView.setVisibility(View.GONE); + } + }); + } + helper.initialize(container, playbackInfo); + } + + @Override + public void play() { + if (helper != null && mediaUri != null) { + helper.play(); + } + } + + @Override + public void pause() { + if (helper != null) helper.pause(); + } + + @Override + public boolean isPlaying() { + return helper != null && helper.isPlaying(); + } + + @Override + public void release() { + if (helper != null) { + helper.release(); + helper = null; + } + } + + @Override + public boolean wantsToPlay() { + return canPlayVideo && mediaUri != null && ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= mStartAutoplayVisibleAreaOffset; + } + + @Override + public int getPlayerOrder() { + return getBindingAdapterPosition(); + } + } + + class PostCard2WithPreviewViewHolder extends PostBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_card_2_with_preview) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_post_card_2_with_preview) + TextView subredditTextView; + @BindView(R.id.user_text_view_item_post_card_2_with_preview) + TextView userTextView; + @BindView(R.id.stickied_post_image_view_item_post_card_2_with_preview) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_card_2_with_preview) + TextView postTimeTextView; + @BindView(R.id.title_text_view_item_post_card_2_with_preview) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_card_2_with_preview) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_card_2_with_preview) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_card_2_with_preview) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_card_2_with_preview) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_card_2_with_preview) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_card_2_with_preview) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_card_2_with_preview) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_card_2_with_preview) + CustomTextView awardsTextView; + @BindView(R.id.link_text_view_item_post_card_2_with_preview) + TextView linkTextView; + @BindView(R.id.video_or_gif_indicator_image_view_item_post_card_2_with_preview) + ImageView videoOrGifIndicatorImageView; + @BindView(R.id.progress_bar_item_post_card_2_with_preview) + ProgressBar progressBar; + @BindView(R.id.image_view_item_post_card_2_with_preview) + AspectRatioGifImageView imageView; + @BindView(R.id.load_image_error_text_view_item_post_card_2_with_preview) + TextView errorTextView; + @BindView(R.id.image_view_no_preview_gallery_item_post_card_2_with_preview) + ImageView noPreviewImageView; + @BindView(R.id.bottom_constraint_layout_item_post_card_2_with_preview) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_card_2_with_preview) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_card_2_with_preview) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_card_2_with_preview) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_card_2_with_preview) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_card_2_with_preview) + ImageView saveButton; + @BindView(R.id.share_button_item_post_card_2_with_preview) + ImageView shareButton; + @BindView(R.id.divider_item_post_card_2_with_preview) + View divider; + RequestListener<Drawable> requestListener; + + PostCard2WithPreviewViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView( + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton, + true); + + if (mActivity.typeface != null) { + linkTextView.setTypeface(mActivity.typeface); + errorTextView.setTypeface(mActivity.typeface); + } + linkTextView.setTextColor(mSecondaryTextColor); + noPreviewImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + noPreviewImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + videoOrGifIndicatorImageView.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN); + videoOrGifIndicatorImageView.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); + errorTextView.setTextColor(mPrimaryTextColor); + divider.setBackgroundColor(mDividerColor); + + imageView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + openMedia(post); + } + }); + + errorTextView.setOnClickListener(view -> { + progressBar.setVisibility(View.VISIBLE); + errorTextView.setVisibility(View.GONE); + loadImage(this); + }); + + noPreviewImageView.setOnClickListener(view -> { + imageView.performClick(); + }); + + requestListener = new RequestListener<>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + errorTextView.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + errorTextView.setVisibility(View.GONE); + progressBar.setVisibility(View.GONE); + return false; + } + }; + } + } + + class PostCard2TextTypeViewHolder extends PostBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_card_2_text) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_post_card_2_text) + TextView subredditTextView; + @BindView(R.id.user_text_view_item_post_card_2_text) + TextView userTextView; + @BindView(R.id.stickied_post_image_view_item_post_card_2_text) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_card_2_text) + TextView postTimeTextView; + @BindView(R.id.title_text_view_item_post_card_2_text) + TextView titleTextView; + @BindView(R.id.content_text_view_item_post_card_2_text) + TextView contentTextView; + @BindView(R.id.type_text_view_item_post_card_2_text) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_card_2_text) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_card_2_text) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_card_2_text) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_card_2_text) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_card_2_text) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_card_2_text) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_card_2_text) + CustomTextView awardsTextView; + @BindView(R.id.bottom_constraint_layout_item_post_card_2_text) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_card_2_text) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_card_2_text) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_card_2_text) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_card_2_text) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_card_2_text) + ImageView saveButton; + @BindView(R.id.share_button_item_post_card_2_text) + ImageView shareButton; + @BindView(R.id.divider_item_post_card_2_text) + View divider; + + PostCard2TextTypeViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView( + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton, + true); + + if (mActivity.contentTypeface != null) { + contentTextView.setTypeface(mActivity.contentTypeface); + } + contentTextView.setTextColor(mPostContentColor); + divider.setBackgroundColor(mDividerColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java new file mode 100644 index 00000000..89b2531c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java @@ -0,0 +1,1030 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; +import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.os.CountDownTimer; +import android.os.Handler; +import android.view.HapticFeedbackConstants; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.DimenRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.res.ResourcesCompat; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.LoadState; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearSmoothScroller; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.transition.AutoTransition; +import androidx.transition.TransitionManager; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.Unbinder; +import im.ene.toro.exoplayer.ExoCreator; +import im.ene.toro.media.PlaybackInfo; +import im.ene.toro.media.VolumeInfo; +import ml.docilealligator.infinityforreddit.FetchPostFilterReadPostsAndConcatenatedSubredditNames; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterface; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.adapters.HistoryPostRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.adapters.Paging3LoadingStateAdapter; +import ml.docilealligator.infinityforreddit.adapters.PostRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIcon; +import ml.docilealligator.infinityforreddit.asynctasks.LoadUserData; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.CustomToroContainer; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; +import ml.docilealligator.infinityforreddit.post.HistoryPostPagingSource; +import ml.docilealligator.infinityforreddit.post.HistoryPostViewModel; +import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import ml.docilealligator.infinityforreddit.postfilter.PostFilterUsage; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link HistoryPostFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class HistoryPostFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + public static final String EXTRA_HISTORY_TYPE = "EHT"; + public static final String EXTRA_FILTER = "EF"; + public static final int HISTORY_TYPE_READ_POSTS = 1; + + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String RECYCLER_VIEW_POSITION_STATE = "RVPS"; + private static final String READ_POST_LIST_STATE = "RPLS"; + private static final String POST_FILTER_STATE = "PFS"; + private static final String POST_FRAGMENT_ID_STATE = "PFIS"; + + @BindView(R.id.swipe_refresh_layout_history_post_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_history_post_fragment) + CustomToroContainer mPostRecyclerView; + @BindView(R.id.fetch_post_info_linear_layout_history_post_fragment) + LinearLayout mFetchPostInfoLinearLayout; + @BindView(R.id.fetch_post_info_image_view_history_post_fragment) + ImageView mFetchPostInfoImageView; + @BindView(R.id.fetch_post_info_text_view_history_post_fragment) + TextView mFetchPostInfoTextView; + HistoryPostViewModel mHistoryPostViewModel; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("gfycat") + Retrofit mGfycatRetrofit; + @Inject + @Named("redgifs") + Retrofit mRedgifsRetrofit; + @Inject + @Named("streamable") + Retrofit mStreamableRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + @Named("post_history") + SharedPreferences mPostHistorySharedPreferences; + @Inject + @Named("post_feed_scrolled_position_cache") + SharedPreferences mPostFeedScrolledPositionSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + ExoCreator mExoCreator; + @Inject + Executor mExecutor; + private RequestManager mGlide; + private BaseActivity activity; + private LinearLayoutManagerBugFixed mLinearLayoutManager; + private StaggeredGridLayoutManager mStaggeredGridLayoutManager; + private MenuItem lazyModeItem; + private long historyPostFragmentId; + private int postType; + private boolean isInLazyMode = false; + private boolean isLazyModePaused = false; + private boolean hasPost = false; + private boolean rememberMutingOptionInPostFeed; + private Boolean masterMutingOption; + private HistoryPostRecyclerViewAdapter mAdapter; + private RecyclerView.SmoothScroller smoothScroller; + private Window window; + private Handler lazyModeHandler; + private LazyModeRunnable lazyModeRunnable; + private CountDownTimer resumeLazyModeCountDownTimer; + private float lazyModeInterval; + private String accountName; + private int maxPosition = -1; + private int postLayout; + private SortType sortType; + private PostFilter postFilter; + private ColorDrawable backgroundSwipeRight; + private ColorDrawable backgroundSwipeLeft; + private Drawable drawableSwipeRight; + private Drawable drawableSwipeLeft; + private int swipeLeftAction; + private int swipeRightAction; + private boolean vibrateWhenActionTriggered; + private float swipeActionThreshold; + private ItemTouchHelper touchHelper; + private ArrayList<String> readPosts; + private Unbinder unbinder; + private Map<String, String> subredditOrUserIcons = new HashMap<>(); + private String accessToken; + private int historyType; + + public HistoryPostFragment() { + // Required empty public constructor + } + + public static HistoryPostFragment newInstance() { + HistoryPostFragment fragment = new HistoryPostFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_history_post, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + unbinder = ButterKnife.bind(this, rootView); + + setHasOptionsMenu(true); + + //EventBus.getDefault().register(this); + + applyTheme(); + + mPostRecyclerView.addOnWindowFocusChangedListener(this::onWindowFocusChanged); + + lazyModeHandler = new Handler(); + + lazyModeInterval = Float.parseFloat(mSharedPreferences.getString(SharedPreferencesUtils.LAZY_MODE_INTERVAL_KEY, "2.5")); + + smoothScroller = new LinearSmoothScroller(activity) { + @Override + protected int getVerticalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + }; + + window = activity.getWindow(); + + Resources resources = getResources(); + + if ((activity != null && activity.isImmersiveInterface())) { + mPostRecyclerView.setPadding(0, 0, 0, ((BaseActivity) activity).getNavBarHeight()); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true)) { + int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); + if (navBarResourceId > 0) { + mPostRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); + } + } + + mGlide = Glide.with(activity); + + lazyModeRunnable = new LazyModeRunnable() { + + @Override + public void run() { + if (isInLazyMode && !isLazyModePaused && mAdapter != null) { + int nPosts = mAdapter.getItemCount(); + if (getCurrentPosition() == -1) { + if (mLinearLayoutManager != null) { + setCurrentPosition(mAdapter.getNextItemPositionWithoutBeingHidden(mLinearLayoutManager.findFirstVisibleItemPosition())); + } else { + int[] into = new int[2]; + setCurrentPosition(mAdapter.getNextItemPositionWithoutBeingHidden(mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[1])); + } + } + + if (getCurrentPosition() != RecyclerView.NO_POSITION && nPosts > getCurrentPosition()) { + incrementCurrentPosition(); + smoothScroller.setTargetPosition(mAdapter.getNextItemPositionWithoutBeingHidden(getCurrentPosition())); + if (mLinearLayoutManager != null) { + mLinearLayoutManager.startSmoothScroll(smoothScroller); + } else { + mStaggeredGridLayoutManager.startSmoothScroll(smoothScroller); + } + } + } + lazyModeHandler.postDelayed(this, (long) (lazyModeInterval * 1000)); + } + }; + + resumeLazyModeCountDownTimer = new CountDownTimer((long) (lazyModeInterval * 1000), (long) (lazyModeInterval * 1000)) { + @Override + public void onTick(long l) { + + } + + @Override + public void onFinish() { + resumeLazyMode(true); + } + }; + + mSwipeRefreshLayout.setEnabled(mSharedPreferences.getBoolean(SharedPreferencesUtils.PULL_TO_REFRESH, true)); + mSwipeRefreshLayout.setOnRefreshListener(this::refresh); + + int recyclerViewPosition = 0; + if (savedInstanceState != null) { + recyclerViewPosition = savedInstanceState.getInt(RECYCLER_VIEW_POSITION_STATE); + + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + readPosts = savedInstanceState.getStringArrayList(READ_POST_LIST_STATE); + postFilter = savedInstanceState.getParcelable(POST_FILTER_STATE); + historyPostFragmentId = savedInstanceState.getLong(POST_FRAGMENT_ID_STATE); + } else { + postFilter = getArguments().getParcelable(EXTRA_FILTER); + historyPostFragmentId = System.currentTimeMillis() + new Random().nextInt(1000); + } + + mPostRecyclerView.setOnTouchListener((view, motionEvent) -> { + if (isInLazyMode) { + pauseLazyMode(true); + } + return false; + }); + + if (activity instanceof RecyclerViewContentScrollingInterface) { + mPostRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + ((RecyclerViewContentScrollingInterface) activity).contentScrollDown(); + } else if (dy < 0) { + ((RecyclerViewContentScrollingInterface) activity).contentScrollUp(); + } + } + }); + } + + accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + historyType = getArguments().getInt(EXTRA_HISTORY_TYPE, HISTORY_TYPE_READ_POSTS); + int defaultPostLayout = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.DEFAULT_POST_LAYOUT_KEY, "0")); + rememberMutingOptionInPostFeed = mSharedPreferences.getBoolean(SharedPreferencesUtils.REMEMBER_MUTING_OPTION_IN_POST_FEED, false); + Locale locale = getResources().getConfiguration().locale; + + if (historyType == HISTORY_TYPE_READ_POSTS) { + postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.HISTORY_POST_LAYOUT_FRONT_PAGE_POST, defaultPostLayout); + + mAdapter = new HistoryPostRecyclerViewAdapter(activity, this, mExecutor, mOauthRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mStreamableRetrofit, mCustomThemeWrapper, locale, + accessToken, accountName, postType, postLayout, true, + mSharedPreferences, mNsfwAndSpoilerSharedPreferences, mPostHistorySharedPreferences, + mExoCreator, new HistoryPostRecyclerViewAdapter.Callback() { + @Override + public void typeChipClicked(int filter) { + /*Intent intent = new Intent(activity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, username); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredPostsActivity.EXTRA_USER_WHERE, where); + intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, filter); + startActivity(intent);*/ + } + + @Override + public void flairChipClicked(String flair) { + /*Intent intent = new Intent(activity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, username); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredPostsActivity.EXTRA_USER_WHERE, where); + intent.putExtra(FilteredPostsActivity.EXTRA_CONTAIN_FLAIR, flair); + startActivity(intent);*/ + } + + @Override + public void nsfwChipClicked() { + /*Intent intent = new Intent(activity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, username); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredPostsActivity.EXTRA_USER_WHERE, where); + intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, Post.NSFW_TYPE); + startActivity(intent);*/ + } + + @Override + public void currentlyBindItem(int position) { + if (maxPosition < position) { + maxPosition = position; + } + } + + @Override + public void delayTransition() { + TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); + } + }); + } + + int nColumns = getNColumns(resources); + if (nColumns == 1) { + mLinearLayoutManager = new LinearLayoutManagerBugFixed(activity); + mPostRecyclerView.setLayoutManager(mLinearLayoutManager); + } else { + mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(nColumns, StaggeredGridLayoutManager.VERTICAL); + mPostRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); + StaggeredGridLayoutManagerItemOffsetDecoration itemDecoration = + new StaggeredGridLayoutManagerItemOffsetDecoration(activity, R.dimen.staggeredLayoutManagerItemOffset, nColumns); + mPostRecyclerView.addItemDecoration(itemDecoration); + } + + if (recyclerViewPosition > 0) { + mPostRecyclerView.scrollToPosition(recyclerViewPosition); + } + + if (postFilter == null) { + FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndReadPosts(mRedditDataRoomDatabase, mExecutor, + new Handler(), null, PostFilterUsage.HISTORY_TYPE, PostFilterUsage.HISTORY_TYPE_USAGE_READ_POSTS, (postFilter, readPostList) -> { + if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { + this.postFilter = postFilter; + postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(accountName + SharedPreferencesUtils.NSFW_BASE, false); + initializeAndBindPostViewModel(accessToken); + } + }); + } else { + initializeAndBindPostViewModel(accessToken); + } + + vibrateWhenActionTriggered = mSharedPreferences.getBoolean(SharedPreferencesUtils.VIBRATE_WHEN_ACTION_TRIGGERED, true); + swipeActionThreshold = Float.parseFloat(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_ACTION_THRESHOLD, "0.3")); + swipeRightAction = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_RIGHT_ACTION, "1")); + swipeLeftAction = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_LEFT_ACTION, "0")); + initializeSwipeActionDrawable(); + + touchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { + boolean exceedThreshold = false; + + @Override + public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { + if (!(viewHolder instanceof PostRecyclerViewAdapter.PostBaseViewHolder) && + !(viewHolder instanceof PostRecyclerViewAdapter.PostCompactBaseViewHolder)) { + return makeMovementFlags(0, 0); + } + int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; + return makeMovementFlags(0, swipeFlags); + } + + @Override + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { + return false; + } + + @Override + public boolean isItemViewSwipeEnabled() { + return true; + } + + @Override + public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { + if (touchHelper != null) { + touchHelper.attachToRecyclerView(null); + touchHelper.attachToRecyclerView(mPostRecyclerView); + if (mAdapter != null) { + mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); + } + } + } + + @Override + public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + + View itemView = viewHolder.itemView; + int horizontalOffset = (int) Utils.convertDpToPixel(16, activity); + if (dX > 0) { + if (dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeRight.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeRight.setBounds(0, 0, 0, 0); + } + + drawableSwipeRight.setBounds(itemView.getLeft() + ((int) dX) - horizontalOffset - drawableSwipeRight.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() - drawableSwipeRight.getIntrinsicHeight()) / 2, + itemView.getLeft() + ((int) dX) - horizontalOffset, + (itemView.getBottom() + itemView.getTop() + drawableSwipeRight.getIntrinsicHeight()) / 2); + backgroundSwipeRight.draw(c); + drawableSwipeRight.draw(c); + } else if (dX < 0) { + if (-dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeLeft.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeLeft.setBounds(0, 0, 0, 0); + } + drawableSwipeLeft.setBounds(itemView.getRight() + ((int) dX) + horizontalOffset, + (itemView.getBottom() + itemView.getTop() - drawableSwipeLeft.getIntrinsicHeight()) / 2, + itemView.getRight() + ((int) dX) + horizontalOffset + drawableSwipeLeft.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() + drawableSwipeLeft.getIntrinsicHeight()) / 2); + backgroundSwipeLeft.draw(c); + drawableSwipeLeft.draw(c); + } + } + + @Override + public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { + return swipeActionThreshold; + } + }); + + if (nColumns == 1 && mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false)) { + touchHelper.attachToRecyclerView(mPostRecyclerView); + } + mPostRecyclerView.setAdapter(mAdapter); + mPostRecyclerView.setCacheManager(mAdapter); + mPostRecyclerView.setPlayerInitializer(order -> { + VolumeInfo volumeInfo = new VolumeInfo(true, 0f); + return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo); + }); + + return rootView; + } + + @Override + public void onResume() { + super.onResume(); + if (mAdapter != null) { + mAdapter.setCanStartActivity(true); + } + if (isInLazyMode) { + resumeLazyMode(false); + } + if (mAdapter != null && mPostRecyclerView != null) { + mPostRecyclerView.onWindowVisibilityChanged(View.VISIBLE); + } + } + + private boolean scrollPostsByCount(int count) { + if (mLinearLayoutManager != null) { + int pos = mLinearLayoutManager.findFirstVisibleItemPosition(); + int targetPosition = pos + count; + mLinearLayoutManager.scrollToPositionWithOffset(targetPosition, 0); + return true; + } else { + return false; + } + } + + @Override + public boolean handleKeyDown(int keyCode) { + boolean volumeKeysNavigatePosts = mSharedPreferences.getBoolean(SharedPreferencesUtils.VOLUME_KEYS_NAVIGATE_POSTS, false); + if (volumeKeysNavigatePosts) { + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + return scrollPostsByCount(-1); + case KeyEvent.KEYCODE_VOLUME_DOWN: + return scrollPostsByCount(1); + } + } + return false; + } + + private int getNColumns(Resources resources) { + final boolean foldEnabled = mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_FOLD_SUPPORT, false); + if (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + switch (postLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD_2: + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT_CARD_LAYOUT_2, "1")); + case SharedPreferencesUtils.POST_LAYOUT_COMPACT: + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT_COMPACT_LAYOUT, "1")); + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT_GALLERY_LAYOUT, "2")); + default: + if (getResources().getBoolean(R.bool.isTablet)) { + if (foldEnabled) { + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT_UNFOLDED, "2")); + } else { + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT, "2")); + } + } + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT, "1")); + } + } else { + switch (postLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD_2: + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE_CARD_LAYOUT_2, "2")); + case SharedPreferencesUtils.POST_LAYOUT_COMPACT: + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE_COMPACT_LAYOUT, "2")); + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE_GALLERY_LAYOUT, "2")); + default: + if (getResources().getBoolean(R.bool.isTablet) && foldEnabled) { + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE_UNFOLDED, "2")); + } + return Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE, "2")); + } + } + } + + private void initializeAndBindPostViewModel(String accessToken) { + if (postType == HistoryPostPagingSource.TYPE_READ_POSTS) { + mHistoryPostViewModel = new ViewModelProvider(HistoryPostFragment.this, new HistoryPostViewModel.Factory(mExecutor, + accessToken == null ? mRetrofit : mOauthRetrofit, mRedditDataRoomDatabase, accessToken, + accountName, mSharedPreferences, HistoryPostPagingSource.TYPE_READ_POSTS, postFilter)).get(HistoryPostViewModel.class); + } else { + mHistoryPostViewModel = new ViewModelProvider(HistoryPostFragment.this, new HistoryPostViewModel.Factory(mExecutor, + accessToken == null ? mRetrofit : mOauthRetrofit, mRedditDataRoomDatabase, accessToken, + accountName, mSharedPreferences, HistoryPostPagingSource.TYPE_READ_POSTS, postFilter)).get(HistoryPostViewModel.class); + } + + bindPostViewModel(); + } + + private void bindPostViewModel() { + mHistoryPostViewModel.getPosts().observe(getViewLifecycleOwner(), posts -> mAdapter.submitData(getViewLifecycleOwner().getLifecycle(), posts)); + + mAdapter.addLoadStateListener(combinedLoadStates -> { + LoadState refreshLoadState = combinedLoadStates.getRefresh(); + LoadState appendLoadState = combinedLoadStates.getAppend(); + + mSwipeRefreshLayout.setRefreshing(refreshLoadState instanceof LoadState.Loading); + if (refreshLoadState instanceof LoadState.NotLoading) { + if (refreshLoadState.getEndOfPaginationReached() && mAdapter.getItemCount() < 1) { + noPostFound(); + } else { + hasPost = true; + } + } else if (refreshLoadState instanceof LoadState.Error) { + mFetchPostInfoLinearLayout.setOnClickListener(view -> refresh()); + showErrorView(R.string.load_posts_error); + } + if (!(refreshLoadState instanceof LoadState.Loading) && appendLoadState instanceof LoadState.NotLoading) { + if (appendLoadState.getEndOfPaginationReached() && mAdapter.getItemCount() < 1) { + noPostFound(); + } + } + return null; + }); + + mPostRecyclerView.setAdapter(mAdapter.withLoadStateFooter(new Paging3LoadingStateAdapter(activity, mCustomThemeWrapper, R.string.load_more_posts_error, + view -> mAdapter.retry()))); + } + + private void noPostFound() { + hasPost = false; + if (isInLazyMode) { + stopLazyMode(); + } + + mFetchPostInfoLinearLayout.setOnClickListener(null); + showErrorView(R.string.no_posts); + } + + private void initializeSwipeActionDrawable() { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + backgroundSwipeRight = new ColorDrawable(mCustomThemeWrapper.getDownvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } else { + backgroundSwipeRight = new ColorDrawable(mCustomThemeWrapper.getUpvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } + + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + backgroundSwipeLeft = new ColorDrawable(mCustomThemeWrapper.getUpvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } else { + backgroundSwipeLeft = new ColorDrawable(mCustomThemeWrapper.getDownvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } + } + + public long getHistoryPostFragmentId() { + return historyPostFragmentId; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (BaseActivity) context; + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putStringArrayList(READ_POST_LIST_STATE, readPosts); + if (mLinearLayoutManager != null) { + outState.putInt(RECYCLER_VIEW_POSITION_STATE, mLinearLayoutManager.findFirstVisibleItemPosition()); + } else if (mStaggeredGridLayoutManager != null) { + int[] into = new int[mStaggeredGridLayoutManager.getSpanCount()]; + outState.putInt(RECYCLER_VIEW_POSITION_STATE, + mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0]); + } + outState.putParcelable(POST_FILTER_STATE, postFilter); + outState.putLong(POST_FRAGMENT_ID_STATE, historyPostFragmentId); + } + + @Override + public void refresh() { + mFetchPostInfoLinearLayout.setVisibility(View.GONE); + hasPost = false; + if (isInLazyMode) { + stopLazyMode(); + } + mAdapter.refresh(); + goBackToTop(); + } + + private void showErrorView(int stringResId) { + if (activity != null && isAdded()) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchPostInfoLinearLayout.setVisibility(View.VISIBLE); + mFetchPostInfoTextView.setText(stringResId); + mGlide.load(R.drawable.error_image).into(mFetchPostInfoImageView); + } + } + + @Override + public boolean startLazyMode() { + if (!hasPost) { + Toast.makeText(activity, R.string.no_posts_no_lazy_mode, Toast.LENGTH_SHORT).show(); + return false; + } + + Utils.setTitleWithCustomFontToMenuItem(activity.typeface, lazyModeItem, getString(R.string.action_stop_lazy_mode)); + + if (mAdapter != null && mAdapter.isAutoplay()) { + mAdapter.setAutoplay(false); + refreshAdapter(); + } + + isInLazyMode = true; + isLazyModePaused = false; + + lazyModeInterval = Float.parseFloat(mSharedPreferences.getString(SharedPreferencesUtils.LAZY_MODE_INTERVAL_KEY, "2.5")); + lazyModeHandler.postDelayed(lazyModeRunnable, (long) (lazyModeInterval * 1000)); + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + Toast.makeText(activity, getString(R.string.lazy_mode_start, lazyModeInterval), + Toast.LENGTH_SHORT).show(); + + return true; + } + + @Override + public void stopLazyMode() { + Utils.setTitleWithCustomFontToMenuItem(activity.typeface, lazyModeItem, getString(R.string.action_start_lazy_mode)); + if (mAdapter != null) { + String autoplayString = mSharedPreferences.getString(SharedPreferencesUtils.VIDEO_AUTOPLAY, SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_NEVER); + if (autoplayString.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ALWAYS_ON) || + (autoplayString.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ON_WIFI) && Utils.isConnectedToWifi(activity))) { + mAdapter.setAutoplay(true); + refreshAdapter(); + } + } + isInLazyMode = false; + isLazyModePaused = false; + lazyModeRunnable.resetOldPosition(); + lazyModeHandler.removeCallbacks(lazyModeRunnable); + resumeLazyModeCountDownTimer.cancel(); + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + Toast.makeText(activity, getString(R.string.lazy_mode_stop), Toast.LENGTH_SHORT).show(); + } + + @Override + public void resumeLazyMode(boolean resumeNow) { + if (isInLazyMode) { + if (mAdapter != null && mAdapter.isAutoplay()) { + mAdapter.setAutoplay(false); + refreshAdapter(); + } + isLazyModePaused = false; + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + lazyModeRunnable.resetOldPosition(); + + if (resumeNow) { + lazyModeHandler.post(lazyModeRunnable); + } else { + lazyModeHandler.postDelayed(lazyModeRunnable, (long) (lazyModeInterval * 1000)); + } + } + } + + @Override + public void pauseLazyMode(boolean startTimer) { + resumeLazyModeCountDownTimer.cancel(); + isInLazyMode = true; + isLazyModePaused = true; + lazyModeHandler.removeCallbacks(lazyModeRunnable); + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + if (startTimer) { + resumeLazyModeCountDownTimer.start(); + } + } + + @Override + public boolean isInLazyMode() { + return isInLazyMode; + } + + @Override + public void changePostLayout(int postLayout) { + changePostLayout(postLayout, false); + } + + public void changePostLayout(int postLayout, boolean temporary) { + this.postLayout = postLayout; + if (!temporary) { + switch (postType) { + case HistoryPostPagingSource.TYPE_READ_POSTS: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.HISTORY_POST_LAYOUT_FRONT_PAGE_POST, postLayout).apply(); + } + } + + int previousPosition = -1; + if (mLinearLayoutManager != null) { + previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + } else if (mStaggeredGridLayoutManager != null) { + int[] into = new int[mStaggeredGridLayoutManager.getSpanCount()]; + previousPosition = mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0]; + } + int nColumns = getNColumns(getResources()); + if (nColumns == 1) { + mLinearLayoutManager = new LinearLayoutManagerBugFixed(activity); + if (mPostRecyclerView.getItemDecorationCount() > 0) { + mPostRecyclerView.removeItemDecorationAt(0); + } + mPostRecyclerView.setLayoutManager(mLinearLayoutManager); + mStaggeredGridLayoutManager = null; + } else { + mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(nColumns, StaggeredGridLayoutManager.VERTICAL); + if (mPostRecyclerView.getItemDecorationCount() > 0) { + mPostRecyclerView.removeItemDecorationAt(0); + } + mPostRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); + StaggeredGridLayoutManagerItemOffsetDecoration itemDecoration = + new StaggeredGridLayoutManagerItemOffsetDecoration(activity, R.dimen.staggeredLayoutManagerItemOffset, nColumns); + mPostRecyclerView.addItemDecoration(itemDecoration); + mLinearLayoutManager = null; + } + + if (previousPosition > 0) { + mPostRecyclerView.scrollToPosition(previousPosition); + } + + if (mAdapter != null) { + mAdapter.setPostLayout(postLayout); + refreshAdapter(); + } + } + + @Override + public void applyTheme() { + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); + mFetchPostInfoTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + if (activity.typeface != null) { + mFetchPostInfoTextView.setTypeface(activity.typeface); + } + } + + @Nullable + public Boolean getMasterMutingOption() { + return masterMutingOption; + } + + public void videoAutoplayChangeMutingOption(boolean isMute) { + if (rememberMutingOptionInPostFeed) { + masterMutingOption = isMute; + } + } + + public void loadIcon(String subredditOrUserName, boolean isSubreddit, PostFragment.LoadIconListener loadIconListener) { + if (subredditOrUserIcons.containsKey(subredditOrUserName)) { + loadIconListener.loadIconSuccess(subredditOrUserName, subredditOrUserIcons.get(subredditOrUserName)); + } else { + if (isSubreddit) { + LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, + subredditOrUserName, accessToken, mOauthRetrofit, mRetrofit, + iconImageUrl -> { + subredditOrUserIcons.put(subredditOrUserName, iconImageUrl); + loadIconListener.loadIconSuccess(subredditOrUserName, iconImageUrl); + }); + } else { + LoadUserData.loadUserData(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditOrUserName, + mRetrofit, iconImageUrl -> { + subredditOrUserIcons.put(subredditOrUserName, iconImageUrl); + loadIconListener.loadIconSuccess(subredditOrUserName, iconImageUrl); + }); + } + } + } + + private void refreshAdapter() { + int previousPosition = -1; + if (mLinearLayoutManager != null) { + previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + } else if (mStaggeredGridLayoutManager != null) { + int[] into = new int[mStaggeredGridLayoutManager.getSpanCount()]; + previousPosition = mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0]; + } + + RecyclerView.LayoutManager layoutManager = mPostRecyclerView.getLayoutManager(); + mPostRecyclerView.setAdapter(null); + mPostRecyclerView.setLayoutManager(null); + mPostRecyclerView.setAdapter(mAdapter); + mPostRecyclerView.setLayoutManager(layoutManager); + if (previousPosition > 0) { + mPostRecyclerView.scrollToPosition(previousPosition); + } + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + if (isInLazyMode) { + lazyModeRunnable.resetOldPosition(); + } + } else if (mStaggeredGridLayoutManager != null) { + mStaggeredGridLayoutManager.scrollToPositionWithOffset(0, 0); + if (isInLazyMode) { + lazyModeRunnable.resetOldPosition(); + } + } + } + + @Override + public void onPause() { + super.onPause(); + if (isInLazyMode) { + pauseLazyMode(false); + } + if (mAdapter != null && mPostRecyclerView != null) { + mPostRecyclerView.onWindowVisibilityChanged(View.GONE); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + unbinder.unbind(); + } + + @Override + public void onDestroy() { + EventBus.getDefault().unregister(this); + if (mPostRecyclerView != null) { + mPostRecyclerView.addOnWindowFocusChangedListener(null); + } + super.onDestroy(); + } + + private void onWindowFocusChanged(boolean hasWindowsFocus) { + if (mAdapter != null) { + mAdapter.setCanPlayVideo(hasWindowsFocus); + } + } + + private static abstract class LazyModeRunnable implements Runnable { + private int currentPosition = -1; + + int getCurrentPosition() { + return currentPosition; + } + + void setCurrentPosition(int currentPosition) { + this.currentPosition = currentPosition; + } + + void incrementCurrentPosition() { + currentPosition++; + } + + void resetOldPosition() { + currentPosition = -1; + } + } + + private static class StaggeredGridLayoutManagerItemOffsetDecoration extends RecyclerView.ItemDecoration { + + private int mItemOffset; + private int mNColumns; + + StaggeredGridLayoutManagerItemOffsetDecoration(int itemOffset, int nColumns) { + mItemOffset = itemOffset; + mNColumns = nColumns; + } + + StaggeredGridLayoutManagerItemOffsetDecoration(@NonNull Context context, @DimenRes int itemOffsetId, int nColumns) { + this(context.getResources().getDimensionPixelSize(itemOffsetId), nColumns); + } + + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, + @NonNull RecyclerView.State state) { + super.getItemOffsets(outRect, view, parent, state); + + StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); + + int spanIndex = layoutParams.getSpanIndex(); + + int halfOffset = mItemOffset / 2; + + if (mNColumns == 2) { + if (spanIndex == 0) { + outRect.set(halfOffset, 0, halfOffset / 2, 0); + } else { + outRect.set(halfOffset / 2, 0, halfOffset, 0); + } + } else if (mNColumns == 3) { + if (spanIndex == 0) { + outRect.set(halfOffset, 0, halfOffset / 2, 0); + } else if (spanIndex == 1) { + outRect.set(halfOffset / 2, 0, halfOffset / 2, 0); + } else { + outRect.set(halfOffset / 2, 0, halfOffset, 0); + } + } + } + } + + public interface LoadIconListener { + void loadIconSuccess(String subredditOrUserName, String iconUrl); + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java index 1d717a3e..5551d31e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java @@ -337,7 +337,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { Resources resources = getResources(); - if ((activity instanceof BaseActivity && ((BaseActivity) activity).isImmersiveInterface())) { + if ((activity != null && activity.isImmersiveInterface())) { mPostRecyclerView.setPadding(0, 0, 0, ((BaseActivity) activity).getNavBarHeight()); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true)) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java new file mode 100644 index 00000000..7f773d29 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java @@ -0,0 +1,126 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.paging.ListenableFuturePagingSource; +import androidx.paging.PagingState; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.concurrent.Executor; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import ml.docilealligator.infinityforreddit.readpost.ReadPost; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.HttpException; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class HistoryPostPagingSource extends ListenableFuturePagingSource<String, Post> { + public static final int TYPE_READ_POSTS = 0; + + private Retrofit retrofit; + private Executor executor; + private RedditDataRoomDatabase redditDataRoomDatabase; + private String accessToken; + private String accountName; + private SharedPreferences sharedPreferences; + private String username; + private int postType; + private PostFilter postFilter; + + public HistoryPostPagingSource(Retrofit retrofit, Executor executor, RedditDataRoomDatabase redditDataRoomDatabase, + String accessToken, String accountName, SharedPreferences sharedPreferences, + String username, int postType, PostFilter postFilter) { + this.retrofit = retrofit; + this.executor = executor; + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.accessToken = accessToken; + this.accountName = accountName; + this.sharedPreferences = sharedPreferences; + this.username = username; + this.postType = postType; + this.postFilter = postFilter; + } + + @Nullable + @Override + public String getRefreshKey(@NonNull PagingState<String, Post> pagingState) { + return null; + } + + @NonNull + @Override + public ListenableFuture<LoadResult<String, Post>> loadFuture(@NonNull LoadParams<String> loadParams) { + if (postType == TYPE_READ_POSTS) { + return loadHomePosts(loadParams, redditDataRoomDatabase); + } else { + return loadHomePosts(loadParams, redditDataRoomDatabase); + } + } + + public LoadResult<String, Post> transformData(List<ReadPost> readPosts) { + StringBuilder ids = new StringBuilder(); + long lastItem = 0; + for (ReadPost readPost : readPosts) { + ids.append("t3_").append(readPost.getId()).append(","); + lastItem = readPost.getTime(); + } + if (ids.length() > 0) { + ids.deleteCharAt(ids.length() - 1); + } + + Call<String> historyPosts; + if (accessToken != null && !accessToken.isEmpty()) { + historyPosts = retrofit.create(RedditAPI.class).getInfoOauth(ids.toString(), APIUtils.getOAuthHeader(accessToken)); + } else { + historyPosts = retrofit.create(RedditAPI.class).getInfo(ids.toString()); + } + + try { + Response<String> response = historyPosts.execute(); + if (response.isSuccessful()) { + String responseString = response.body(); + LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null); + if (newPosts == null) { + return new LoadResult.Error<>(new Exception("Error parsing posts")); + } else { + if (newPosts.size() < 25) { + return new LoadResult.Page<>(new ArrayList<>(newPosts), null, null); + } + return new LoadResult.Page<>(new ArrayList<>(newPosts), null, Long.toString(lastItem)); + } + } else { + return new LoadResult.Error<>(new Exception("Response failed")); + } + } catch (IOException e) { + e.printStackTrace(); + return new LoadResult.Error<>(new Exception("Response failed")); + } + } + + private ListenableFuture<LoadResult<String, Post>> loadHomePosts(@NonNull LoadParams<String> loadParams, RedditDataRoomDatabase redditDataRoomDatabase) { + String before = loadParams.getKey(); + ListenableFuture<List<ReadPost>> readPosts = redditDataRoomDatabase.readPostDao().getAllReadPostsListenableFuture(username, Long.parseLong(before == null ? Long.toString(System.currentTimeMillis()) : before)); + + ListenableFuture<LoadResult<String, Post>> pageFuture = Futures.transform(readPosts, this::transformData, executor); + + ListenableFuture<LoadResult<String, Post>> partialLoadResultFuture = + Futures.catching(pageFuture, HttpException.class, + LoadResult.Error::new, executor); + + return Futures.catching(partialLoadResultFuture, + IOException.class, LoadResult.Error::new, executor); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostViewModel.java new file mode 100644 index 00000000..be68ce32 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostViewModel.java @@ -0,0 +1,115 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Transformations; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelKt; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.Pager; +import androidx.paging.PagingConfig; +import androidx.paging.PagingData; +import androidx.paging.PagingLiveData; + +import java.util.concurrent.Executor; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import retrofit2.Retrofit; + +public class HistoryPostViewModel extends ViewModel { + private Executor executor; + private Retrofit retrofit; + private RedditDataRoomDatabase redditDataRoomDatabase; + private String accessToken; + private String accountName; + private SharedPreferences sharedPreferences; + private int postType; + private PostFilter postFilter; + + private LiveData<PagingData<Post>> posts; + + private MutableLiveData<PostFilter> postFilterLiveData; + + public HistoryPostViewModel(Executor executor, Retrofit retrofit, RedditDataRoomDatabase redditDataRoomDatabase, + String accessToken, String accountName, SharedPreferences sharedPreferences, + int postType, PostFilter postFilter) { + this.executor = executor; + this.retrofit = retrofit; + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.accessToken = accessToken; + this.accountName = accountName; + this.sharedPreferences = sharedPreferences; + this.postType = postType; + this.postFilter = postFilter; + + postFilterLiveData = new MutableLiveData<>(); + postFilterLiveData.postValue(postFilter); + + Pager<String, Post> pager = new Pager<>(new PagingConfig(25, 25, false), this::returnPagingSoruce); + + posts = Transformations.switchMap(postFilterLiveData, postFilterValue -> PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), ViewModelKt.getViewModelScope(this))); + } + + public LiveData<PagingData<Post>> getPosts() { + return posts; + } + + public HistoryPostPagingSource returnPagingSoruce() { + HistoryPostPagingSource paging3PagingSource; + switch (postType) { + case HistoryPostPagingSource.TYPE_READ_POSTS: + paging3PagingSource = new HistoryPostPagingSource(retrofit, executor, redditDataRoomDatabase, accessToken, accountName, + sharedPreferences, accountName, postType, postFilter); + break; + default: + paging3PagingSource = new HistoryPostPagingSource(retrofit, executor, redditDataRoomDatabase, accessToken, accountName, + sharedPreferences, accountName, postType, postFilter); + break; + } + return paging3PagingSource; + } + + public void changePostFilter(PostFilter postFilter) { + postFilterLiveData.postValue(postFilter); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Executor executor; + private Retrofit retrofit; + private RedditDataRoomDatabase redditDataRoomDatabase; + private String accessToken; + private String accountName; + private SharedPreferences sharedPreferences; + private int postType; + private PostFilter postFilter; + + public Factory(Executor executor, Retrofit retrofit, RedditDataRoomDatabase redditDataRoomDatabase, + String accessToken, String accountName, SharedPreferences sharedPreferences, int postType, + PostFilter postFilter) { + this.executor = executor; + this.retrofit = retrofit; + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.accessToken = accessToken; + this.accountName = accountName; + this.sharedPreferences = sharedPreferences; + this.postType = postType; + this.postFilter = postFilter; + } + + @NonNull + @Override + public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { + if (postType == HistoryPostPagingSource.TYPE_READ_POSTS) { + return (T) new HistoryPostViewModel(executor, retrofit, redditDataRoomDatabase, accessToken, accountName, sharedPreferences, + postType, postFilter); + } else { + return (T) new HistoryPostViewModel(executor, retrofit, redditDataRoomDatabase, accessToken, accountName, sharedPreferences, + postType, postFilter); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/postfilter/PostFilterUsage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/postfilter/PostFilterUsage.java index 558abeeb..5e4005b8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/postfilter/PostFilterUsage.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/postfilter/PostFilterUsage.java @@ -17,6 +17,8 @@ public class PostFilterUsage implements Parcelable { public static final int USER_TYPE = 3; public static final int MULTIREDDIT_TYPE = 4; public static final int SEARCH_TYPE = 5; + public static final int HISTORY_TYPE = 6; + public static final String HISTORY_TYPE_USAGE_READ_POSTS = "-read-posts"; public static final String NO_USAGE = "--"; @NonNull diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPost.java index 2a3da252..6dfcceae 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPost.java @@ -21,15 +21,19 @@ public class ReadPost implements Parcelable { @NonNull @ColumnInfo(name = "id") private String id; + @ColumnInfo(name = "time") + private long time; public ReadPost(@NonNull String username, @NonNull String id) { this.username = username; this.id = id; + this.time = System.currentTimeMillis(); } protected ReadPost(Parcel in) { username = in.readString(); id = in.readString(); + time = in.readLong(); } public static final Creator<ReadPost> CREATOR = new Creator<ReadPost>() { @@ -62,6 +66,14 @@ public class ReadPost implements Parcelable { this.id = id; } + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + @Override public int describeContents() { return 0; @@ -71,6 +83,7 @@ public class ReadPost implements Parcelable { public void writeToParcel(Parcel parcel, int i) { parcel.writeString(username); parcel.writeString(id); + parcel.writeLong(time); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java index 2390f59a..f446811d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java @@ -5,6 +5,8 @@ import androidx.room.Insert; import androidx.room.OnConflictStrategy; import androidx.room.Query; +import com.google.common.util.concurrent.ListenableFuture; + import java.util.List; @Dao @@ -12,6 +14,9 @@ public interface ReadPostDao { @Insert(onConflict = OnConflictStrategy.REPLACE) void insert(ReadPost readPost); + @Query("SELECT * FROM read_posts WHERE username = :username AND time < :before ORDER BY :before LIMIT 25") + ListenableFuture<List<ReadPost>> getAllReadPostsListenableFuture(String username, long before); + @Query("SELECT * FROM read_posts WHERE username = :username") List<ReadPost> getAllReadPosts(String username); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java index a6d27c62..cadb24cd 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java @@ -68,6 +68,7 @@ public class SharedPreferencesUtils { public static final String POST_LAYOUT_MULTI_REDDIT_POST_BASE = "post_layout_multi_reddit_post_"; public static final String POST_LAYOUT_USER_POST_BASE = "post_layout_user_post_"; public static final String POST_LAYOUT_SEARCH_POST = "post_layout_search_post"; + public static final String HISTORY_POST_LAYOUT_FRONT_PAGE_POST = "history_post_layout_read_post"; public static final int POST_LAYOUT_CARD = 0; public static final int POST_LAYOUT_COMPACT = 1; public static final int POST_LAYOUT_GALLERY = 2; diff --git a/app/src/main/res/layout/activity_history.xml b/app/src/main/res/layout/activity_history.xml new file mode 100644 index 00000000..c03e976f --- /dev/null +++ b/app/src/main/res/layout/activity_history.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/coordinator_layout_history_activity" + tools:context=".activities.HistoryActivity"> + + <com.google.android.material.appbar.AppBarLayout + android:id="@+id/appbar_layout_history_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <com.google.android.material.appbar.CollapsingToolbarLayout + android:id="@+id/collapsing_toolbar_layout_history_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_scrollFlags="scroll|enterAlways" + app:titleEnabled="false" + app:toolbarId="@+id/toolbar_history_activity"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar_history_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?attr/actionBarSize" + app:layout_collapseMode="pin" + app:layout_scrollFlags="scroll|enterAlways" + app:popupTheme="@style/AppTheme.PopupOverlay" + app:navigationIcon="?attr/homeAsUpIndicator" /> + + </com.google.android.material.appbar.CollapsingToolbarLayout> + + <com.google.android.material.tabs.TabLayout + android:id="@+id/tab_layout_tab_layout_history_activity_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + app:layout_scrollFlags="scroll|enterAlways" + app:tabGravity="fill" + app:tabIndicatorHeight="3dp" + app:tabMode="fixed" + app:tabRippleColor="?attr/colorControlHighlight" + app:tabUnboundedRipple="false" /> + + </com.google.android.material.appbar.AppBarLayout> + + <androidx.viewpager2.widget.ViewPager2 + android:id="@+id/view_pager_history_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_history_post.xml b/app/src/main/res/layout/fragment_history_post.xml new file mode 100644 index 00000000..74765bb6 --- /dev/null +++ b/app/src/main/res/layout/fragment_history_post.xml @@ -0,0 +1,46 @@ +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:application="ml.docilealligator.infinityforreddit.fragments.HistoryPostFragment"> + + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + android:id="@+id/swipe_refresh_layout_history_post_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ml.docilealligator.infinityforreddit.customviews.CustomToroContainer + android:id="@+id/recycler_view_history_post_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipToPadding="false" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> + + <LinearLayout + android:id="@+id/fetch_post_info_linear_layout_history_post_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginTop="48dp" + android:layout_marginBottom="48dp" + android:gravity="center" + android:orientation="vertical" + android:visibility="gone"> + + <ImageView + android:id="@+id/fetch_post_info_image_view_history_post_fragment" + android:layout_width="150dp" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/fetch_post_info_text_view_history_post_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </LinearLayout> + +</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/app/src/main/res/menu/history_activity.xml b/app/src/main/res/menu/history_activity.xml new file mode 100644 index 00000000..ab473564 --- /dev/null +++ b/app/src/main/res/menu/history_activity.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_refresh_history_activity" + android:orderInCategory="1" + android:title="@string/action_refresh" + app:showAsAction="never" /> + + <item + android:id="@+id/action_change_post_layout_history_activity" + android:orderInCategory="2" + android:title="@string/action_change_post_layout" + app:showAsAction="never" /> +</menu>
\ 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 0f555a22..9fb9f6bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,6 +45,7 @@ <string name="wiki_activity_label">Wiki</string> <string name="edit_profile_activity_label">Edit Profile</string> <string name="post_poll_activity_label">Poll Post</string> + <string name="history_activity_label">History</string> <string name="navigation_drawer_open">Open navigation drawer</string> <string name="navigation_drawer_close">Close navigation drawer</string> |