From 4397e09016c53306562757d467b0aa9d60d0571f Mon Sep 17 00:00:00 2001 From: Balazs Toldi Date: Fri, 27 Oct 2023 15:10:00 +0200 Subject: [PATCH] Merge changes from Infinity This commit merges the changes that were made in the upstream infinity repo --- .gitignore | 2 + app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 28 +- app/src/main/ic_launcher-playstore.png | Bin 0 -> 33818 bytes .../toldi/infinityforlemmy/AppComponent.java | 15 +- .../RedditDataRoomDatabase.java | 25 +- .../CommentFilterPreferenceActivity.java | 126 + .../CommentFilterUsageListingActivity.java | 181 + .../CustomizeCommentFilterActivity.java | 302 + .../CustomizePostFilterActivity.java | 4 - .../activities/HistoryActivity.java | 336 -- .../activities/MainActivity.java | 9 +- .../PostFilterPreferenceActivity.java | 24 +- .../PostFilterUsageListingActivity.java | 6 +- .../activities/SearchActivity.java | 26 +- .../activities/SearchResultActivity.java | 10 +- .../SubscribedThingListingActivity.java | 8 + .../ViewSubredditDetailActivity.java | 29 +- .../activities/ViewUserDetailActivity.java | 2 +- .../activities/ViewVideoActivity.java | 87 +- ...ilterUsageEmbeddedRecyclerViewAdapter.java | 76 + ...CommentFilterUsageRecyclerViewAdapter.java | 80 + ...entFilterWithUsageRecyclerViewAdapter.java | 81 + .../CommentsListingRecyclerViewAdapter.java | 220 +- .../adapters/CommentsRecyclerViewAdapter.java | 368 +- .../HistoryPostRecyclerViewAdapter.java | 4896 ----------------- .../PostDetailRecyclerViewAdapter.java | 1868 +++---- ...stFilterWithUsageRecyclerViewAdapter.java} | 50 +- .../adapters/PostRecyclerViewAdapter.java | 3659 ++++++++---- .../SearchActivityRecyclerViewAdapter.java | 32 +- ...ilterUsageEmbeddedRecyclerViewAdapter.java | 102 + .../infinityforlemmy/apis/RedditAPI.java | 52 +- ...mmentFilterOptionsBottomSheetFragment.java | 63 + ...FilterUsageOptionsBottomSheetFragment.java | 57 + ...CommentFilterUsageBottomSheetFragment.java | 48 + .../PostFilterOptionsBottomSheetFragment.java | 25 +- .../PostLayoutBottomSheetFragment.java | 35 +- .../RedditAPIInfoBottomSheetFragment.java | 73 - .../comment/CommentViewModel.java | 7 +- .../comment/FetchComment.java | 10 +- .../comment/ParseComment.java | 24 +- .../commentfilter/CommentFilter.java | 122 + .../commentfilter/CommentFilterDao.java | 47 + .../commentfilter/CommentFilterUsage.java | 61 + .../commentfilter/CommentFilterUsageDao.java | 31 + .../CommentFilterUsageViewModel.java | 41 + .../commentfilter/CommentFilterWithUsage.java | 16 + .../CommentFilterWithUsageViewModel.java | 39 + .../commentfilter/DeleteCommentFilter.java | 12 + .../DeleteCommentFilterUsage.java | 13 + .../commentfilter/FetchCommentFilter.java | 25 + .../commentfilter/SaveCommentFilter.java | 38 + .../commentfilter/SaveCommentFilterUsage.java | 13 + .../customtheme/CustomTheme.java | 136 +- .../customtheme/CustomThemeSettingsItem.java | 8 + .../customtheme/CustomThemeWrapper.java | 32 + .../InterceptTouchEventLinearLayout.java | 31 + .../customviews/slidr/widget/SliderPanel.java | 2 +- .../fragments/CommentsListingFragment.java | 2 +- .../fragments/HistoryPostFragment.java | 1445 ----- .../ThemePreviewCommentsFragment.java | 186 +- .../fragments/ThemePreviewPostsFragment.java | 164 +- .../fragments/ViewImgurVideoFragment.java | 57 +- .../fragments/ViewPostDetailFragment.java | 69 +- .../ViewRedditGalleryVideoFragment.java | 35 +- .../message/MessageViewModel.java | 3 +- .../multireddit/MultiRedditViewModel.java | 3 +- .../post/HistoryPostViewModel.java | 5 +- .../infinityforlemmy/post/PostViewModel.java | 24 +- .../postfilter/PostFilterDao.java | 7 +- .../postfilter/PostFilterWithUsage.java | 16 + ...java => PostFilterWithUsageViewModel.java} | 17 +- .../DeleteRecentSearchQuery.java | 44 - .../InsertRecentSearchQuery.java | 41 +- .../RecentSearchQueryDao.java | 3 + .../services/DownloadRedditVideoService.java | 38 +- .../settings/MainPreferenceFragment.java | 17 + .../shortcut/ShortcutManager.java | 37 + .../subreddit/SubredditListingViewModel.java | 3 +- .../SubscribedSubredditViewModel.java | 3 +- .../SubscribedUserViewModel.java | 3 +- .../user/UserListingViewModel.java | 3 +- .../infinityforlemmy/utils/APIUtils.java | 6 - .../CustomThemeSharedPreferencesUtils.java | 4 + .../utils/MaterialYouUtils.java | 3 + .../utils/SharedPreferencesUtils.java | 5 +- .../splash_branding.png | Bin 0 -> 38940 bytes .../res/drawable-xxxhdpi/splash_branding.png | Bin 0 -> 31997 bytes .../exo_player_control_view_background.xml | 10 + .../main/res/drawable/ic_arrow_back_24dp.xml | 11 + .../main/res/drawable/ic_delete_all_24.xml | 10 + .../main/res/drawable/ic_downvote_24dp.xml | 9 + .../res/drawable/ic_downvote_filled_24dp.xml | 9 + .../res/drawable/ic_fast_forward_24dp.xml | 10 + .../main/res/drawable/ic_fast_rewind_24dp.xml | 10 + .../ic_file_download_toolbar_white_24dp.xml | 11 +- app/src/main/res/drawable/ic_mute_24dp.xml | 4 +- .../drawable/ic_mute_white_rounded_24dp.xml | 9 - ...ite_rounded_24dp.xml => ic_pause_24dp.xml} | 0 ...ounded_24dp.xml => ic_play_arrow_24dp.xml} | 0 app/src/main/res/drawable/ic_unmute_24dp.xml | 4 +- .../drawable/ic_unmute_white_rounded_24dp.xml | 9 - app/src/main/res/drawable/ic_upvote_24dp.xml | 9 + .../res/drawable/ic_upvote_filled_24dp.xml | 9 + app/src/main/res/drawable/splash_screen.xml | 11 +- .../activity_comment_filter_preference.xml | 52 + .../activity_comment_filter_usage_listing.xml | 52 + .../activity_customize_comment_filter.xml | 171 + .../layout/activity_customize_post_filter.xml | 34 +- .../main/res/layout/activity_post_poll.xml | 12 +- app/src/main/res/layout/activity_search.xml | 23 +- .../res/layout/activity_view_post_detail.xml | 2 +- ..._post_or_comment_filter_name_of_usage.xml} | 7 +- .../layout/dialog_go_to_thing_edit_text.xml | 2 +- .../main/res/layout/dialog_insert_link.xml | 4 +- .../exo_autoplay_playback_control_view.xml | 6 +- ..._autoplay_playback_control_view_legacy.xml | 12 +- .../res/layout/exo_playback_control_view.xml | 203 +- ...nt_comment_filter_options_bottom_sheet.xml | 70 + ...ment_filter_usage_options_bottom_sheet.xml | 52 + ... fragment_important_info_bottom_sheet.xml} | 4 +- ..._new_comment_filter_usage_bottom_sheet.xml | 34 + ...gment_post_filter_options_bottom_sheet.xml | 2 +- ... => fragment_post_layout_bottom_sheet.xml} | 16 + ...lery_item_caption_and_url_bottom_sheet.xml | 4 +- .../fragment_theme_preview_comments.xml | 298 +- .../layout/fragment_theme_preview_posts.xml | 130 +- app/src/main/res/layout/item_comment.xml | 83 +- .../item_comment_filter_usage_embedded.xml | 9 + .../layout/item_comment_filter_with_usage.xml | 28 + .../layout/item_post_card_2_gallery_type.xml | 83 +- .../main/res/layout/item_post_card_2_text.xml | 91 +- .../item_post_card_2_video_autoplay.xml | 89 +- ...ard_2_video_autoplay_legacy_controller.xml | 91 +- .../layout/item_post_card_2_with_preview.xml | 91 +- .../layout/item_post_card_3_gallery_type.xml | 265 + .../main/res/layout/item_post_card_3_text.xml | 243 + .../item_post_card_3_video_type_autoplay.xml | 265 + ..._video_type_autoplay_legacy_controller.xml | 265 + .../layout/item_post_card_3_with_preview.xml | 382 ++ app/src/main/res/layout/item_post_compact.xml | 111 +- .../item_post_compact_right_thumbnail.xml | 111 +- .../res/layout/item_post_detail_gallery.xml | 99 +- ...tem_post_detail_image_and_gif_autoplay.xml | 103 +- .../main/res/layout/item_post_detail_link.xml | 103 +- .../layout/item_post_detail_no_preview.xml | 167 +- .../main/res/layout/item_post_detail_text.xml | 103 +- ...item_post_detail_video_and_gif_preview.xml | 103 +- .../item_post_detail_video_autoplay.xml | 103 +- ...etail_video_autoplay_legacy_controller.xml | 103 +- app/src/main/res/layout/item_post_filter.xml | 14 - .../item_post_filter_usage_embedded.xml | 9 + .../layout/item_post_filter_with_usage.xml | 28 + .../res/layout/item_post_gallery_type.xml | 83 +- app/src/main/res/layout/item_post_text.xml | 93 +- .../layout/item_post_video_type_autoplay.xml | 93 +- ..._video_type_autoplay_legacy_controller.xml | 93 +- .../res/layout/item_post_with_preview.xml | 93 +- .../res/layout/item_recent_search_query.xml | 19 +- .../customize_comment_filter_activity.xml | 17 + .../menu/view_subreddit_detail_activity.xml | 12 +- app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 4809 -> 4994 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 4809 -> 4994 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2993 -> 3073 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 2993 -> 3073 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 6830 -> 7121 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 6830 -> 7121 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 10847 -> 11383 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10847 -> 11383 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 15190 -> 16249 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 15190 -> 16249 bytes app/src/main/res/values-el/strings.xml | 1259 +++++ app/src/main/res/values-ko/strings.xml | 520 ++ app/src/main/res/values-night-v31/styles.xml | 14 + app/src/main/res/values-night/colors.xml | 2 +- app/src/main/res/values-ta/strings.xml | 754 +++ app/src/main/res/values-v31/styles.xml | 14 + app/src/main/res/values/arrays.xml | 10 + app/src/main/res/values/colors.xml | 2 +- app/src/main/res/values/strings.xml | 80 +- app/src/main/res/xml/main_preferences.xml | 5 + gradle.properties | 5 +- 182 files changed, 12490 insertions(+), 11105 deletions(-) create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterPreferenceActivity.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterUsageListingActivity.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizeCommentFilterActivity.java delete mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/activities/HistoryActivity.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageEmbeddedRecyclerViewAdapter.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageRecyclerViewAdapter.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterWithUsageRecyclerViewAdapter.java delete mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/adapters/HistoryPostRecyclerViewAdapter.java rename app/src/main/java/eu/toldi/infinityforlemmy/adapters/{PostFilterRecyclerViewAdapter.java => PostFilterWithUsageRecyclerViewAdapter.java} (50%) create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/adapters/navigationdrawer/PostFilterUsageEmbeddedRecyclerViewAdapter.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterOptionsBottomSheetFragment.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterUsageOptionsBottomSheetFragment.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/NewCommentFilterUsageBottomSheetFragment.java delete mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/RedditAPIInfoBottomSheetFragment.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilter.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterDao.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsage.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageDao.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageViewModel.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsage.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsageViewModel.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilter.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilterUsage.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/FetchCommentFilter.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilter.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilterUsage.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/customviews/InterceptTouchEventLinearLayout.java delete mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterWithUsage.java rename app/src/main/java/eu/toldi/infinityforlemmy/postfilter/{PostFilterViewModel.java => PostFilterWithUsageViewModel.java} (55%) delete mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/DeleteRecentSearchQuery.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/shortcut/ShortcutManager.java create mode 100644 app/src/main/res/drawable-night-xxxhdpi/splash_branding.png create mode 100644 app/src/main/res/drawable-xxxhdpi/splash_branding.png create mode 100644 app/src/main/res/drawable/exo_player_control_view_background.xml create mode 100644 app/src/main/res/drawable/ic_arrow_back_24dp.xml create mode 100644 app/src/main/res/drawable/ic_delete_all_24.xml create mode 100644 app/src/main/res/drawable/ic_downvote_24dp.xml create mode 100644 app/src/main/res/drawable/ic_downvote_filled_24dp.xml create mode 100644 app/src/main/res/drawable/ic_fast_forward_24dp.xml create mode 100644 app/src/main/res/drawable/ic_fast_rewind_24dp.xml delete mode 100644 app/src/main/res/drawable/ic_mute_white_rounded_24dp.xml rename app/src/main/res/drawable/{ic_pause_white_rounded_24dp.xml => ic_pause_24dp.xml} (100%) rename app/src/main/res/drawable/{ic_play_arrow_white_rounded_24dp.xml => ic_play_arrow_24dp.xml} (100%) delete mode 100644 app/src/main/res/drawable/ic_unmute_white_rounded_24dp.xml create mode 100644 app/src/main/res/drawable/ic_upvote_24dp.xml create mode 100644 app/src/main/res/drawable/ic_upvote_filled_24dp.xml create mode 100644 app/src/main/res/layout/activity_comment_filter_preference.xml create mode 100644 app/src/main/res/layout/activity_comment_filter_usage_listing.xml create mode 100644 app/src/main/res/layout/activity_customize_comment_filter.xml rename app/src/main/res/layout/{dialog_edit_post_filter_name_of_usage.xml => dialog_edit_post_or_comment_filter_name_of_usage.xml} (78%) create mode 100644 app/src/main/res/layout/fragment_comment_filter_options_bottom_sheet.xml create mode 100644 app/src/main/res/layout/fragment_comment_filter_usage_options_bottom_sheet.xml rename app/src/main/res/layout/{fragment_reddit_api_info_bottom_sheet.xml => fragment_important_info_bottom_sheet.xml} (94%) create mode 100644 app/src/main/res/layout/fragment_new_comment_filter_usage_bottom_sheet.xml rename app/src/main/res/layout/{fragment_post_layot_bottom_sheet.xml => fragment_post_layout_bottom_sheet.xml} (82%) create mode 100644 app/src/main/res/layout/item_comment_filter_usage_embedded.xml create mode 100644 app/src/main/res/layout/item_comment_filter_with_usage.xml create mode 100644 app/src/main/res/layout/item_post_card_3_gallery_type.xml create mode 100644 app/src/main/res/layout/item_post_card_3_text.xml create mode 100644 app/src/main/res/layout/item_post_card_3_video_type_autoplay.xml create mode 100644 app/src/main/res/layout/item_post_card_3_video_type_autoplay_legacy_controller.xml create mode 100644 app/src/main/res/layout/item_post_card_3_with_preview.xml delete mode 100644 app/src/main/res/layout/item_post_filter.xml create mode 100644 app/src/main/res/layout/item_post_filter_usage_embedded.xml create mode 100644 app/src/main/res/layout/item_post_filter_with_usage.xml create mode 100644 app/src/main/res/menu/customize_comment_filter_activity.xml create mode 100644 app/src/main/res/values-el/strings.xml create mode 100644 app/src/main/res/values-ko/strings.xml create mode 100644 app/src/main/res/values-night-v31/styles.xml create mode 100644 app/src/main/res/values-ta/strings.xml create mode 100644 app/src/main/res/values-v31/styles.xml diff --git a/.gitignore b/.gitignore index 5bfaa113..769def11 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,8 @@ gen-external-apklibs # NDK obj/ +**/ndkHelperBin +**/.cxx # IntelliJ IDEA *.iml diff --git a/app/build.gradle b/app/build.gradle index 09a5c5f2..f0bd26a6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -232,7 +232,7 @@ dependencies { implementation 'com.github.santalu:aspect-ratio-imageview:1.0.9' implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.23' def bivVersion = "1.8.1" - implementation "com.github.piasy:BigImageViewer:bivVersion" + implementation "com.github.piasy:BigImageViewer:$bivVersion" implementation "com.github.piasy:GlideImageLoader:$bivVersion" implementation "com.github.piasy:GlideImageViewFactory:$bivVersion" @@ -271,6 +271,8 @@ dependencies { implementation 'com.otaliastudios:zoomlayout:1.9.0' + implementation 'androidx.core:core-splashscreen:1.0.1' + /**** Builds and flavors ****/ // debugImplementation because LeakCanary should only run in debug builds. diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a3b05a9f..3f01470a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + xmlns:tools="http://schemas.android.com/tools" + package="eu.toldi.infinityforlemmy"> @@ -22,6 +23,7 @@ android:maxSdkVersion="28" /> + + + + - + @@ -499,6 +514,7 @@ android:name=".activities.ViewUserDetailActivity" android:parentActivityName=".activities.MainActivity" android:theme="@style/AppTheme.Slidable" /> + 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 BnL_{o literal 0 HcmV?d00001 diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java b/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java index 7997aaf3..82101cd7 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java @@ -12,9 +12,12 @@ import eu.toldi.infinityforlemmy.activities.AccountPostsActivity; import eu.toldi.infinityforlemmy.activities.AccountSavedThingActivity; import eu.toldi.infinityforlemmy.activities.BlockedThingListingActivity; import eu.toldi.infinityforlemmy.activities.CommentActivity; +import eu.toldi.infinityforlemmy.activities.CommentFilterPreferenceActivity; +import eu.toldi.infinityforlemmy.activities.CommentFilterUsageListingActivity; import eu.toldi.infinityforlemmy.activities.CreateMultiRedditActivity; import eu.toldi.infinityforlemmy.activities.CustomThemeListingActivity; import eu.toldi.infinityforlemmy.activities.CustomThemePreviewActivity; +import eu.toldi.infinityforlemmy.activities.CustomizeCommentFilterActivity; import eu.toldi.infinityforlemmy.activities.CustomizePostFilterActivity; import eu.toldi.infinityforlemmy.activities.CustomizeThemeActivity; import eu.toldi.infinityforlemmy.activities.EditCommentActivity; @@ -25,7 +28,6 @@ import eu.toldi.infinityforlemmy.activities.FetchRandomSubredditOrPostActivity; import eu.toldi.infinityforlemmy.activities.FilteredPostsActivity; import eu.toldi.infinityforlemmy.activities.FullMarkdownActivity; import eu.toldi.infinityforlemmy.activities.GiveAwardActivity; -import eu.toldi.infinityforlemmy.activities.HistoryActivity; import eu.toldi.infinityforlemmy.activities.InboxActivity; import eu.toldi.infinityforlemmy.activities.InstanceInfoActivity; import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; @@ -75,7 +77,6 @@ import eu.toldi.infinityforlemmy.fragments.BlockedCommunitiesListingFragment; import eu.toldi.infinityforlemmy.fragments.BlockedUsersListingFragment; import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment; import eu.toldi.infinityforlemmy.fragments.FollowedUsersListingFragment; -import eu.toldi.infinityforlemmy.fragments.HistoryPostFragment; import eu.toldi.infinityforlemmy.fragments.InboxFragment; import eu.toldi.infinityforlemmy.fragments.MorePostsInfoFragment; import eu.toldi.infinityforlemmy.fragments.MultiRedditListingFragment; @@ -309,10 +310,6 @@ public interface AppComponent { void inject(MaterialYouWorker materialYouWorker); - void inject(HistoryPostFragment historyPostFragment); - - void inject(HistoryActivity historyActivity); - void inject(MorePostsInfoFragment morePostsInfoFragment); void inject(BlockedThingListingActivity blockedThingListingActivity); @@ -327,6 +324,12 @@ public interface AppComponent { void inject(@NotNull InstanceInfoActivity instanceInfoActivity); + void inject(CommentFilterPreferenceActivity commentFilterPreferenceActivity); + + void inject(CustomizeCommentFilterActivity customizeCommentFilterActivity); + + void inject(CommentFilterUsageListingActivity commentFilterUsageListingActivity); + @Component.Factory interface Factory { AppComponent create(@BindsInstance Application application); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/RedditDataRoomDatabase.java b/app/src/main/java/eu/toldi/infinityforlemmy/RedditDataRoomDatabase.java index d2b131d6..21291f5e 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/RedditDataRoomDatabase.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/RedditDataRoomDatabase.java @@ -17,6 +17,10 @@ import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityDao; import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData; import eu.toldi.infinityforlemmy.blockeduser.BlockedUserDao; import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterDao; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsageDao; import eu.toldi.infinityforlemmy.customtheme.CustomTheme; import eu.toldi.infinityforlemmy.customtheme.CustomThemeDao; import eu.toldi.infinityforlemmy.multireddit.AnonymousMultiredditSubreddit; @@ -42,7 +46,8 @@ import eu.toldi.infinityforlemmy.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, BlockedUserData.class, BlockedCommunityData.class}, version = 27) + ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class, + BlockedUserData.class, BlockedCommunityData.class, CommentFilter.class, CommentFilterUsage.class}, version = 28) public abstract class RedditDataRoomDatabase extends RoomDatabase { public static RedditDataRoomDatabase create(final Context context) { @@ -53,7 +58,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_22_23, MIGRATION_23_24, MIGRATION_24_25, MIGRATION_25_26, MIGRATION_26_27) + MIGRATION_21_22, MIGRATION_22_23, MIGRATION_23_24, MIGRATION_24_25, MIGRATION_25_26, MIGRATION_26_27, MIGRATION_27_28) .build(); } @@ -85,6 +90,10 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { public abstract AnonymousMultiredditSubredditDao anonymousMultiredditSubredditDao(); + public abstract CommentFilterDao commentFilterDao(); + + public abstract CommentFilterUsageDao commentFilterUsageDao(); + private static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { @@ -424,4 +433,16 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { + " ADD COLUMN is_favorite INTEGER DEFAULT 0 NOT NULL"); } }; + + private static final Migration MIGRATION_27_28 = new Migration(27, 28) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("ALTER TABLE custom_themes ADD COLUMN filled_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#E6F4FF") + " NOT NULL"); + database.execSQL("ALTER TABLE custom_themes ADD COLUMN read_post_filled_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#F5F5F5") + " NOT NULL"); + database.execSQL("CREATE TABLE comment_filter " + + "(name TEXT NOT NULL PRIMARY KEY, max_vote INTEGER NOT NULL, min_vote INTEGER NOT NULL, exclude_strings TEXT, exclude_users TEXT)"); + database.execSQL("CREATE TABLE comment_filter_usage (name TEXT NOT NULL, usage INTEGER NOT NULL, " + + "name_of_usage TEXT NOT NULL, PRIMARY KEY(name, usage, name_of_usage), FOREIGN KEY(name) REFERENCES comment_filter(name) ON DELETE CASCADE)"); + } + }; } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterPreferenceActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterPreferenceActivity.java new file mode 100644 index 00000000..7fbd3883 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterPreferenceActivity.java @@ -0,0 +1,126 @@ +package eu.toldi.infinityforlemmy.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModelProvider; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.ButterKnife; +import eu.toldi.infinityforlemmy.Infinity; +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; +import eu.toldi.infinityforlemmy.adapters.CommentFilterWithUsageRecyclerViewAdapter; +import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentFilterOptionsBottomSheetFragment; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; +import eu.toldi.infinityforlemmy.commentfilter.DeleteCommentFilter; +import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; +import eu.toldi.infinityforlemmy.databinding.ActivityCommentFilterPreferenceBinding; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterWithUsageViewModel; +import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; + +public class CommentFilterPreferenceActivity extends BaseActivity { + + private ActivityCommentFilterPreferenceBinding binding; + + @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + @Inject + Executor executor; + public CommentFilterWithUsageViewModel commentFilterWithUsageViewModel; + private CommentFilterWithUsageRecyclerViewAdapter adapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + binding = ActivityCommentFilterPreferenceBinding.inflate(getLayoutInflater()); + + setContentView(binding.getRoot()); + + ButterKnife.bind(this); + + applyCustomTheme(); + + setSupportActionBar(binding.toolbarCommentFilterPreferenceActivity); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + binding.fabCommentFilterPreferenceActivity.setOnClickListener(view -> { + Intent intent = new Intent(this, CustomizeCommentFilterActivity.class); + intent.putExtra(CustomizeCommentFilterActivity.EXTRA_FROM_SETTINGS, true); + startActivity(intent); + }); + + adapter = new CommentFilterWithUsageRecyclerViewAdapter(this, commentFilter -> { + CommentFilterOptionsBottomSheetFragment commentFilterOptionsBottomSheetFragment = new CommentFilterOptionsBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(CommentFilterOptionsBottomSheetFragment.EXTRA_POST_FILTER, commentFilter); + commentFilterOptionsBottomSheetFragment.setArguments(bundle); + commentFilterOptionsBottomSheetFragment.show(getSupportFragmentManager(), commentFilterOptionsBottomSheetFragment.getTag()); + }); + + binding.recyclerViewCommentFilterPreferenceActivity.setAdapter(adapter); + + commentFilterWithUsageViewModel = new ViewModelProvider(this, + new CommentFilterWithUsageViewModel.Factory(redditDataRoomDatabase)).get(CommentFilterWithUsageViewModel.class); + + commentFilterWithUsageViewModel.getCommentFilterWithUsageListLiveData().observe(this, commentFilterWithUsages -> adapter.setCommentFilterWithUsageList(commentFilterWithUsages)); + } + + public void editCommentFilter(CommentFilter commentFilter) { + Intent intent = new Intent(this, CustomizeCommentFilterActivity.class); + intent.putExtra(CustomizeCommentFilterActivity.EXTRA_COMMENT_FILTER, commentFilter); + intent.putExtra(CustomizeCommentFilterActivity.EXTRA_FROM_SETTINGS, true); + startActivity(intent); + } + + public void applyCommentFilterTo(CommentFilter commentFilter) { + Intent intent = new Intent(this, CommentFilterUsageListingActivity.class); + intent.putExtra(CommentFilterUsageListingActivity.EXTRA_COMMENT_FILTER, commentFilter); + startActivity(intent); + } + + public void deleteCommentFilter(CommentFilter commentFilter) { + DeleteCommentFilter.deleteCommentFilter(redditDataRoomDatabase, executor, commentFilter); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return sharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return customThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCommentFilterPreferenceActivity, binding.collapsingToolbarLayoutCommentFilterPreferenceActivity, binding.toolbarCommentFilterPreferenceActivity); + applyFABTheme(binding.fabCommentFilterPreferenceActivity, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); + binding.getRoot().setBackgroundColor(customThemeWrapper.getBackgroundColor()); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterUsageListingActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterUsageListingActivity.java new file mode 100644 index 00000000..1c63c792 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CommentFilterUsageListingActivity.java @@ -0,0 +1,181 @@ +package eu.toldi.infinityforlemmy.activities; + +import android.app.Activity; + +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.os.Bundle; +import android.os.Handler; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModelProvider; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import eu.toldi.infinityforlemmy.Infinity; +import eu.toldi.infinityforlemmy.R; +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; +import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentFilterUsageOptionsBottomSheetFragment; +import eu.toldi.infinityforlemmy.bottomsheetfragments.NewCommentFilterUsageBottomSheetFragment; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsageViewModel; +import eu.toldi.infinityforlemmy.commentfilter.DeleteCommentFilterUsage; +import eu.toldi.infinityforlemmy.commentfilter.SaveCommentFilterUsage; +import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; +import eu.toldi.infinityforlemmy.databinding.ActivityCommentFilterUsageListingBinding; +import eu.toldi.infinityforlemmy.adapters.CommentFilterUsageRecyclerViewAdapter; +import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; +import eu.toldi.infinityforlemmy.utils.Utils; + +public class CommentFilterUsageListingActivity extends BaseActivity { + + public static final String EXTRA_COMMENT_FILTER = "ECF"; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + @Inject + Executor executor; + private ActivityCommentFilterUsageListingBinding binding; + public CommentFilterUsageViewModel commentFilterUsageViewModel; + private CommentFilterUsageRecyclerViewAdapter adapter; + private CommentFilter commentFilter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + binding = ActivityCommentFilterUsageListingBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + applyCustomTheme(); + + setSupportActionBar(binding.toolbarCommentFilterUsageListingActivity); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + commentFilter = getIntent().getParcelableExtra(EXTRA_COMMENT_FILTER); + + setTitle(commentFilter.name); + + binding.fabCommentFilterUsageListingActivity.setOnClickListener(view -> { + NewCommentFilterUsageBottomSheetFragment newCommentFilterUsageBottomSheetFragment = new NewCommentFilterUsageBottomSheetFragment(); + newCommentFilterUsageBottomSheetFragment.show(getSupportFragmentManager(), newCommentFilterUsageBottomSheetFragment.getTag()); + }); + + adapter = new CommentFilterUsageRecyclerViewAdapter(this, customThemeWrapper, commentFilterUsage -> { + CommentFilterUsageOptionsBottomSheetFragment commentFilterUsageOptionsBottomSheetFragment = new CommentFilterUsageOptionsBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(CommentFilterUsageOptionsBottomSheetFragment.EXTRA_COMMENT_FILTER_USAGE, commentFilterUsage); + commentFilterUsageOptionsBottomSheetFragment.setArguments(bundle); + commentFilterUsageOptionsBottomSheetFragment.show(getSupportFragmentManager(), commentFilterUsageOptionsBottomSheetFragment.getTag()); + }); + binding.recyclerViewCommentFilterUsageListingActivity.setAdapter(adapter); + + commentFilterUsageViewModel = new ViewModelProvider(this, + new CommentFilterUsageViewModel.Factory(redditDataRoomDatabase, commentFilter.name)).get(CommentFilterUsageViewModel.class); + + commentFilterUsageViewModel.getCommentFilterUsageListLiveData().observe(this, commentFilterUsages -> adapter.setCommentFilterUsages(commentFilterUsages)); + } + + public void newCommentFilterUsage(int type) { + switch (type) { + case CommentFilterUsage.SUBREDDIT_TYPE: + editAndCommentFilterUsageNameOfUsage(type, null); + break; + } + } + + private void editAndCommentFilterUsageNameOfUsage(int type, String nameOfUsage) { + View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_or_comment_filter_name_of_usage, null); + TextView messageTextView = dialogView.findViewById(R.id.message_text_view_edit_post_or_comment_filter_name_of_usage_dialog); + messageTextView.setVisibility(View.GONE); + TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_or_comment_filter_name_of_usage_dialog); + TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_or_comment_filter_name_of_usage_dialog); + int primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + textInputLayout.setBoxStrokeColor(primaryTextColor); + textInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + textInputEditText.setTextColor(primaryTextColor); + if (nameOfUsage != null) { + textInputEditText.setText(nameOfUsage); + } + textInputEditText.requestFocus(); + int titleStringId = R.string.community; + switch (type) { + case CommentFilterUsage.SUBREDDIT_TYPE: + textInputEditText.setHint(R.string.settings_tab_community_name); + break; + } + + Utils.showKeyboard(this, new Handler(), textInputEditText); + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleStringId) + .setView(dialogView) + .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) + -> { + Utils.hideKeyboard(this); + + CommentFilterUsage commentFilterUsage; + if (!textInputEditText.getText().toString().equals("")) { + commentFilterUsage = new CommentFilterUsage(commentFilter.name, type, textInputEditText.getText().toString()); + SaveCommentFilterUsage.saveCommentFilterUsage(redditDataRoomDatabase, executor, commentFilterUsage); + } + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(editTextDialogInterface -> { + Utils.hideKeyboard(this); + }) + .show(); + } + + public void editCommentFilterUsage(CommentFilterUsage commentFilterUsage) { + editAndCommentFilterUsageNameOfUsage(commentFilterUsage.usage, commentFilterUsage.nameOfUsage); + } + + public void deleteCommentFilterUsage(CommentFilterUsage commentFilterUsage) { + DeleteCommentFilterUsage.deleteCommentFilterUsage(redditDataRoomDatabase, executor, commentFilterUsage); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return sharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return customThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCommentFilterUsageListingActivity, binding.collapsingToolbarLayoutCommentFilterUsageListingActivity, binding.toolbarCommentFilterUsageListingActivity); + applyFABTheme(binding.fabCommentFilterUsageListingActivity, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); + binding.getRoot().setBackgroundColor(customThemeWrapper.getBackgroundColor()); + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizeCommentFilterActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizeCommentFilterActivity.java new file mode 100644 index 00000000..151e88f0 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizeCommentFilterActivity.java @@ -0,0 +1,302 @@ +package eu.toldi.infinityforlemmy.activities; + +import android.app.Activity; + +import android.Manifest; +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.res.ColorStateList; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.concurrent.Executor; +import java.util.regex.PatternSyntaxException; + +import javax.inject.Inject; +import javax.inject.Named; + +import eu.toldi.infinityforlemmy.Infinity; +import eu.toldi.infinityforlemmy.R; +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; +import eu.toldi.infinityforlemmy.commentfilter.SaveCommentFilter; +import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; +import eu.toldi.infinityforlemmy.databinding.ActivityCustomizeCommentFilterBinding; +import eu.toldi.infinityforlemmy.utils.Utils; + + +public class CustomizeCommentFilterActivity extends BaseActivity { + + public static final String EXTRA_COMMENT_FILTER = "ECF"; + public static final String EXTRA_FROM_SETTINGS = "EFS"; + public static final String RETURN_EXTRA_COMMENT_FILTER = "RECF"; + private static final String COMMENT_FILTER_STATE = "CFS"; + private static final String ORIGINAL_NAME_STATE = "ONS"; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences currentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + private CommentFilter commentFilter; + private boolean fromSettings; + private String originalName; + private ActivityCustomizeCommentFilterBinding binding; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + binding = ActivityCustomizeCommentFilterBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(binding.appbarLayoutCustomizeCommentFilterActivity); + } + + setSupportActionBar(binding.toolbarCustomizeCommentFilterActivity); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(binding.toolbarCustomizeCommentFilterActivity); + + ActivityResultLauncher requestAddUsersLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Intent data = result.getData(); + if (data == null) { + return; + } + + ArrayList usernames = data.getStringArrayListExtra(SearchActivity.RETURN_EXTRA_SELECTED_USERNAMES); + String currentUsers = binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.getText().toString().trim(); + if (usernames != null && !usernames.isEmpty()) { + if (!currentUsers.isEmpty() && currentUsers.charAt(currentUsers.length() - 1) != ',') { + String newString = currentUsers + ","; + binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setText(newString); + } + StringBuilder stringBuilder = new StringBuilder(); + for (String s : usernames) { + stringBuilder.append(s).append(","); + } + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.append(stringBuilder.toString()); + } + }); + + binding.addUsersImageViewCustomizeCommentFilterActivity.setOnClickListener(view -> { + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_USERS, true); + intent.putExtra(SearchActivity.EXTRA_IS_MULTI_SELECTION, true); + requestAddUsersLauncher.launch(intent); + }); + + fromSettings = getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS, false); + + if (savedInstanceState != null) { + commentFilter = savedInstanceState.getParcelable(COMMENT_FILTER_STATE); + originalName = savedInstanceState.getString(ORIGINAL_NAME_STATE); + } else { + commentFilter = getIntent().getParcelableExtra(EXTRA_COMMENT_FILTER); + if (commentFilter == null) { + commentFilter = new CommentFilter(); + originalName = ""; + } else { + if (!fromSettings) { + originalName = ""; + } else { + originalName = commentFilter.name; + } + } + bindView(); + } + } + + private void bindView() { + binding.nameTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.name); + binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.excludeStrings); + binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.excludeUsers); + binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.minVote)); + binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.maxVote)); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + binding.getRoot().setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCustomizeCommentFilterActivity, binding.collapsingToolbarLayoutCustomizeCommentFilterActivity, binding.toolbarCustomizeCommentFilterActivity); + int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + int primaryIconColor = mCustomThemeWrapper.getPrimaryIconColor(); + Drawable cursorDrawable = Utils.getTintedDrawable(this, R.drawable.edit_text_cursor, primaryTextColor); + binding.nameTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.nameTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + binding.excludeUsersTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + binding.addUsersImageViewCustomizeCommentFilterActivity.setImageDrawable(Utils.getTintedDrawable(this, R.drawable.ic_add_24dp, primaryIconColor)); + binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + } else { + setCursorDrawableColor(binding.nameTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + setCursorDrawableColor(binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + setCursorDrawableColor(binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + setCursorDrawableColor(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + setCursorDrawableColor(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + } + + if (typeface != null) { + Utils.setFontToAllTextViews(binding.getRoot(), typeface); + } + } + + public void setCursorDrawableColor(EditText editText, int color) { + try { + Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); + fCursorDrawableRes.setAccessible(true); + int mCursorDrawableRes = fCursorDrawableRes.getInt(editText); + Field fEditor = TextView.class.getDeclaredField("mEditor"); + fEditor.setAccessible(true); + Object editor = fEditor.get(editText); + Class clazz = editor.getClass(); + Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable"); + fCursorDrawable.setAccessible(true); + Drawable[] drawables = new Drawable[2]; + drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN); + drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN); + fCursorDrawable.set(editor, drawables); + } catch (Throwable ignored) { + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.customize_comment_filter_activity, menu); + if (fromSettings) { + menu.findItem(R.id.action_save_customize_comment_filter_activity).setVisible(false); + } + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } else if (item.getItemId() == R.id.action_save_customize_comment_filter_activity) { + try { + constructCommentFilter(); + Intent returnIntent = new Intent(); + returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } catch (PatternSyntaxException e) { + Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show(); + } + + return true; + } else if (item.getItemId() == R.id.action_save_to_database_customize_comment_filter_activity) { + try { + constructCommentFilter(); + + if (!commentFilter.name.equals("")) { + saveCommentFilter(originalName); + } else { + Toast.makeText(CustomizeCommentFilterActivity.this, R.string.comment_filter_requires_a_name, Toast.LENGTH_LONG).show(); + } + } catch (PatternSyntaxException e) { + Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show(); + } + } + return false; + } + + private void saveCommentFilter(String originalName) { + SaveCommentFilter.saveCommentFilter(mExecutor, new Handler(), mRedditDataRoomDatabase, commentFilter, originalName, + new SaveCommentFilter.SaveCommentFilterListener() { + @Override + public void success() { + Intent returnIntent = new Intent(); + returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } + + @Override + public void duplicate() { + new MaterialAlertDialogBuilder(CustomizeCommentFilterActivity.this, R.style.MaterialAlertDialogTheme) + .setTitle(getString(R.string.duplicate_comment_filter_dialog_title, commentFilter.name)) + .setMessage(R.string.duplicate_comment_filter_dialog_message) + .setPositiveButton(R.string.override, (dialogInterface, i) -> saveCommentFilter(commentFilter.name)) + .setNegativeButton(R.string.cancel, null) + .show(); + } + }); + } + + private void constructCommentFilter() throws PatternSyntaxException { + commentFilter.name = binding.nameTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); + commentFilter.excludeStrings = binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); + commentFilter.excludeUsers = binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); + commentFilter.maxVote = binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString()); + commentFilter.minVote = binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString()); + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelable(COMMENT_FILTER_STATE, commentFilter); + outState.putString(ORIGINAL_NAME_STATE, originalName); + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizePostFilterActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizePostFilterActivity.java index def85dfe..ee578e3e 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizePostFilterActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/CustomizePostFilterActivity.java @@ -226,10 +226,6 @@ public class CustomizePostFilterActivity extends BaseActivity { applyCustomTheme(); - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { addOnOffsetChangedListener(appBarLayout); } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/HistoryActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/HistoryActivity.java deleted file mode 100644 index 5c2a35f0..00000000 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/HistoryActivity.java +++ /dev/null @@ -1,336 +0,0 @@ -package eu.toldi.infinityforlemmy.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 org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import eu.toldi.infinityforlemmy.ActivityToolbarInterface; -import eu.toldi.infinityforlemmy.Infinity; -import eu.toldi.infinityforlemmy.R; -import eu.toldi.infinityforlemmy.bottomsheetfragments.PostLayoutBottomSheetFragment; -import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; -import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; -import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent; -import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; -import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment; -import eu.toldi.infinityforlemmy.fragments.HistoryPostFragment; -import eu.toldi.infinityforlemmy.fragments.PostFragment; -import eu.toldi.infinityforlemmy.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 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)) { - mSliderPanel = Slidr.attach(this); - } - - //mViewPager2 = viewPager2; - - 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(); - } - } - - @Override - public void lockSwipeRightToGoBack() { - if (mSliderPanel != null) { - mSliderPanel.lock(); - } - } - - @Override - public void unlockSwipeRightToGoBack() { - if (mSliderPanel != null) { - mSliderPanel.unlock(); - } - } - - @Override - public void postLayoutSelected(int postLayout) { - if (sectionsPagerAdapter != null) { - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.HISTORY_POST_LAYOUT_READ_POST, 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 HistoryPostFragment) { - ((HistoryPostFragment) 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/eu/toldi/infinityforlemmy/activities/MainActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/MainActivity.java index d3e84ef8..292bd562 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/MainActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/MainActivity.java @@ -33,6 +33,7 @@ import androidx.appcompat.app.AppCompatDelegate; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; +import androidx.core.splashscreen.SplashScreen; import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; @@ -249,6 +250,8 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb @Override protected void onCreate(Bundle savedInstanceState) { + SplashScreen.installSplashScreen(this); + ((Infinity) getApplication()).getAppComponent().inject(this); setTheme(R.style.AppTheme_NoActionBarWithTransparentStatusBar); @@ -823,8 +826,6 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } else if (stringId == R.string.multi_reddit) { intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); - } else if (stringId == R.string.history) { - intent = new Intent(MainActivity.this, HistoryActivity.class); } else if (stringId == R.string.trending) { intent = new Intent(MainActivity.this, TrendingActivity.class); } else if (stringId == R.string.upvoted) { @@ -926,7 +927,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb sectionsPagerAdapter = new SectionsPagerAdapter(this, tabCount, mShowFavoriteMultiReddits, mShowMultiReddits, mShowFavoriteSubscribedSubreddits, mShowSubscribedSubreddits); viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(1); + viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); if (mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true)) { if (mShowFavoriteMultiReddits || mShowMultiReddits || mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) { @@ -1665,7 +1666,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } public void doNotShowRedditAPIInfoAgain() { - mInternalSharedPreferences.edit().putBoolean(SharedPreferencesUtils.DO_NOT_SHOW_REDDIT_API_INFO_AGAIN, true).apply(); + mInternalSharedPreferences.edit().putBoolean(SharedPreferencesUtils.DO_NOT_SHOW_REDDIT_API_INFO_V2_AGAIN, true).apply(); } private class SectionsPagerAdapter extends FragmentStateAdapter { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterPreferenceActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterPreferenceActivity.java index f2cafb74..d42a9751 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterPreferenceActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterPreferenceActivity.java @@ -8,6 +8,7 @@ import android.view.MenuItem; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.RecyclerView; @@ -16,6 +17,7 @@ import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; +import java.util.List; import java.util.concurrent.Executor; import javax.inject.Inject; @@ -26,13 +28,14 @@ import butterknife.ButterKnife; import eu.toldi.infinityforlemmy.Infinity; import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; -import eu.toldi.infinityforlemmy.adapters.PostFilterRecyclerViewAdapter; +import eu.toldi.infinityforlemmy.adapters.PostFilterWithUsageRecyclerViewAdapter; import eu.toldi.infinityforlemmy.bottomsheetfragments.PostFilterOptionsBottomSheetFragment; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.post.Post; import eu.toldi.infinityforlemmy.postfilter.DeletePostFilter; import eu.toldi.infinityforlemmy.postfilter.PostFilter; -import eu.toldi.infinityforlemmy.postfilter.PostFilterViewModel; +import eu.toldi.infinityforlemmy.postfilter.PostFilterWithUsageViewModel; +import eu.toldi.infinityforlemmy.postfilter.PostFilterWithUsage; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; public class PostFilterPreferenceActivity extends BaseActivity { @@ -62,8 +65,8 @@ public class PostFilterPreferenceActivity extends BaseActivity { CustomThemeWrapper customThemeWrapper; @Inject Executor executor; - public PostFilterViewModel postFilterViewModel; - private PostFilterRecyclerViewAdapter adapter; + public PostFilterWithUsageViewModel postFilterWithUsageViewModel; + private PostFilterWithUsageRecyclerViewAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { @@ -99,7 +102,7 @@ public class PostFilterPreferenceActivity extends BaseActivity { } }); - adapter = new PostFilterRecyclerViewAdapter(this, customThemeWrapper, postFilter -> { + adapter = new PostFilterWithUsageRecyclerViewAdapter(this, customThemeWrapper, postFilter -> { if (post != null) { showPostFilterOptions(post, postFilter); } else if (subredditName != null) { @@ -117,10 +120,15 @@ public class PostFilterPreferenceActivity extends BaseActivity { recyclerView.setAdapter(adapter); - postFilterViewModel = new ViewModelProvider(this, - new PostFilterViewModel.Factory(redditDataRoomDatabase)).get(PostFilterViewModel.class); + postFilterWithUsageViewModel = new ViewModelProvider(this, + new PostFilterWithUsageViewModel.Factory(redditDataRoomDatabase)).get(PostFilterWithUsageViewModel.class); - postFilterViewModel.getPostFilterListLiveData().observe(this, postFilters -> adapter.setPostFilterList(postFilters)); + postFilterWithUsageViewModel.getPostFilterWithUsageListLiveData().observe(this, new Observer>() { + @Override + public void onChanged(List postFilterWithUsages) { + adapter.setPostFilterWithUsageList(postFilterWithUsages); + } + }); } public void showPostFilterOptions(Post post, PostFilter postFilter) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterUsageListingActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterUsageListingActivity.java index 1a1c1dfe..8b30ba58 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterUsageListingActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/PostFilterUsageListingActivity.java @@ -126,9 +126,9 @@ public class PostFilterUsageListingActivity extends BaseActivity { } private void editAndPostFilterUsageNameOfUsage(int type, String nameOfUsage) { - View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_filter_name_of_usage, null); - TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_filter_name_of_usage_dialog); - TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_filter_name_of_usage_dialog); + View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_or_comment_filter_name_of_usage, null); + TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_or_comment_filter_name_of_usage_dialog); + TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_or_comment_filter_name_of_usage_dialog); int primaryTextColor = customThemeWrapper.getPrimaryTextColor(); textInputLayout.setBoxStrokeColor(primaryTextColor); textInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchActivity.java index dedfda1f..a0f768ba 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchActivity.java @@ -3,6 +3,7 @@ package eu.toldi.infinityforlemmy.activities; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.ColorStateList; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -27,11 +28,14 @@ import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.util.ArrayList; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; @@ -47,7 +51,6 @@ import eu.toldi.infinityforlemmy.apis.RedditAPI; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; -import eu.toldi.infinityforlemmy.recentsearchquery.DeleteRecentSearchQuery; import eu.toldi.infinityforlemmy.recentsearchquery.RecentSearchQuery; import eu.toldi.infinityforlemmy.recentsearchquery.RecentSearchQueryViewModel; import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData; @@ -98,6 +101,8 @@ public class SearchActivity extends BaseActivity { ImageView clearSearchTextImageView; @BindView(R.id.link_handler_image_view_search_activity) ImageView linkHandlerImageView; + @BindView(R.id.delete_all_recent_searches_button_search_activity) + MaterialButton deleteAllSearchesButton; @BindView(R.id.subreddit_name_relative_layout_search_activity) RelativeLayout subredditNameRelativeLayout; @BindView(R.id.search_in_text_view_search_activity) @@ -124,6 +129,8 @@ public class SearchActivity extends BaseActivity { SharedPreferences mNsfwAndSpoilerSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor executor; private String mAccountName; private String mAccessToken; private String query; @@ -163,6 +170,7 @@ public class SearchActivity extends BaseActivity { setSupportActionBar(toolbar); clearSearchTextImageView.setVisibility(View.GONE); + deleteAllSearchesButton.setVisibility(View.GONE); searchOnlySubreddits = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_SUBREDDITS, false); searchOnlyUsers = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_USERS, false); @@ -276,6 +284,17 @@ public class SearchActivity extends BaseActivity { } }); + deleteAllSearchesButton.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.confirm) + .setMessage(R.string.confirm_delete_all_recent_searches) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> { + executor.execute(() -> mRedditDataRoomDatabase.recentSearchQueryDao().deleteAllRecentSearchQueries(mAccountName)); + }) + .setNegativeButton(R.string.no, null) + .show(); + }); + if (savedInstanceState != null) { subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); @@ -319,7 +338,7 @@ public class SearchActivity extends BaseActivity { @Override public void onDelete(RecentSearchQuery recentSearchQuery) { - DeleteRecentSearchQuery.deleteRecentSearchQueryListener(mRedditDataRoomDatabase, recentSearchQuery, () -> {}); + executor.execute(() -> mRedditDataRoomDatabase.recentSearchQueryDao().deleteRecentSearchQueries(recentSearchQuery)); } }); recyclerView.setVisibility(View.VISIBLE); @@ -334,8 +353,10 @@ public class SearchActivity extends BaseActivity { mRecentSearchQueryViewModel.getAllRecentSearchQueries().observe(this, recentSearchQueries -> { if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) { divider.setVisibility(View.VISIBLE); + deleteAllSearchesButton.setVisibility(View.VISIBLE); } else { divider.setVisibility(View.GONE); + deleteAllSearchesButton.setVisibility(View.GONE); } adapter.setRecentSearchQueries(recentSearchQueries); }); @@ -401,6 +422,7 @@ public class SearchActivity extends BaseActivity { linkHandlerImageView.setColorFilter(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); int colorAccent = mCustomThemeWrapper.getColorAccent(); searchInTextView.setTextColor(colorAccent); + deleteAllSearchesButton.setIconTint(ColorStateList.valueOf(mCustomThemeWrapper.getPrimaryIconColor())); subredditNameTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); if (typeface != null) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchResultActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchResultActivity.java index e4f20ba5..88563a52 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchResultActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/SearchResultActivity.java @@ -38,6 +38,7 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.util.ArrayList; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; @@ -130,10 +131,11 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect SharedPreferences mCurrentAccountSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor executor; private Call subredditAutocompleteCall; private String mAccessToken; private String mAccountName; - private String mAccountQualifiedName; private String mQuery; private String mSubredditName; @@ -244,7 +246,7 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect private void bindView(Bundle savedInstanceState) { sectionsPagerAdapter = new SectionsPagerAdapter(this); viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(3); + viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override @@ -392,8 +394,8 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect }); if (mAccountName != null && mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SEARCH_HISTORY, true) && !mInsertSearchQuerySuccess && mQuery != null) { - InsertRecentSearchQuery.insertRecentSearchQueryListener(mRedditDataRoomDatabase, mAccountQualifiedName, - mQuery, () -> mInsertSearchQuerySuccess = true); + InsertRecentSearchQuery.insertRecentSearchQueryListener(executor, new Handler(getMainLooper()), + mRedditDataRoomDatabase, mAccountQualifiedName, mQuery, () -> mInsertSearchQuerySuccess = true); } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/SubscribedThingListingActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/SubscribedThingListingActivity.java index 337387b5..8a5cee75 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/SubscribedThingListingActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/SubscribedThingListingActivity.java @@ -112,6 +112,9 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti @Named("current_account") SharedPreferences mCurrentAccountSharedPreferences; @Inject + @Named("internal") + SharedPreferences mInternalSharedPreferences; + @Inject CustomThemeWrapper mCustomThemeWrapper; @Inject Executor mExecutor; @@ -323,6 +326,10 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti } public void loadSubscriptions(boolean forceLoad) { + if (!forceLoad && System.currentTimeMillis() - mInternalSharedPreferences.getLong(SharedPreferencesUtils.SUBSCRIBED_THINGS_SYNC_TIME, 0L) < 24 * 60 * 60 * 1000) { + return; + } + if (mAccessToken != null && !(!forceLoad && mInsertSuccess)) { FetchSubscribedThing.fetchSubscribedThing(mRetrofit.getRetrofit(), mAccessToken, mAccountQualifiedName, null, new ArrayList<>(), new ArrayList<>(), @@ -332,6 +339,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti public void onFetchSubscribedThingSuccess(ArrayList subscribedSubredditData, ArrayList subscribedUserData, ArrayList subredditData) { + mInternalSharedPreferences.edit().putLong(SharedPreferencesUtils.SUBSCRIBED_THINGS_SYNC_TIME, System.currentTimeMillis()).apply(); InsertSubscribedThings.insertSubscribedThings( mExecutor, new Handler(), diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewSubredditDetailActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewSubredditDetailActivity.java index 6720f856..2e1422b9 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewSubredditDetailActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewSubredditDetailActivity.java @@ -1,9 +1,13 @@ package eu.toldi.infinityforlemmy.activities; +import static android.graphics.BitmapFactory.decodeResource; + import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.PorterDuff; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -40,6 +44,8 @@ import androidx.viewpager2.widget.ViewPager2; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestManager; import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.transition.Transition; import com.evernote.android.state.State; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; @@ -104,6 +110,7 @@ import eu.toldi.infinityforlemmy.post.MarkPostAsRead; import eu.toldi.infinityforlemmy.post.Post; import eu.toldi.infinityforlemmy.post.PostPagingSource; import eu.toldi.infinityforlemmy.readpost.InsertReadPost; +import eu.toldi.infinityforlemmy.shortcut.ShortcutManager; import eu.toldi.infinityforlemmy.subreddit.CommunitySubscription; import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData; import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData; @@ -260,6 +267,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp private int subscribedColor; private int fabOption; private MaterialAlertDialogBuilder nsfwWarningBuilder; + private Bitmap subredditIconBitmap; private boolean showStatistics; @@ -575,11 +583,23 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp .into(iconGifImageView); iconGifImageView.setOnClickListener(null); } else { - glide.load(subredditData.getIconUrl()) + glide.asBitmap() + .load(subredditData.getIconUrl()) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) .error(glide.load(R.drawable.subreddit_default_icon) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0)))) - .into(iconGifImageView); + .into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + subredditIconBitmap = resource; + iconGifImageView.setImageBitmap(resource); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + subredditIconBitmap = null; + } + }); iconGifImageView.setOnClickListener(view -> { Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewImageOrGifActivity.class); intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, subredditData.getIconUrl()); @@ -1148,7 +1168,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp } }); viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(2); + viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { switch (position) { @@ -1274,6 +1294,9 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp } }); return true; + } else if (itemId == R.id.action_add_to_home_screen_view_subreddit_detail_activity) { + Bitmap icon = subredditIconBitmap == null ? decodeResource(getResources(), R.drawable.subreddit_default_icon) : subredditIconBitmap; + return ShortcutManager.requestPinShortcut(this, qualifiedName, icon); } return false; } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewUserDetailActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewUserDetailActivity.java index c1676e62..5d724c9c 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewUserDetailActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewUserDetailActivity.java @@ -761,7 +761,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele private void initializeViewPager() { sectionsPagerAdapter = new SectionsPagerAdapter(this); viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(2); + viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { switch (position) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java index 59192ae5..449a7c87 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java @@ -23,14 +23,11 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.provider.Settings; -import android.text.Html; import android.view.Menu; import android.view.MenuItem; import android.view.OrientationEventListener; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; @@ -70,6 +67,7 @@ import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.video.VideoSize; import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.button.MaterialButton; import com.google.android.material.snackbar.Snackbar; import com.google.common.collect.ImmutableList; import com.otaliastudios.zoom.ZoomEngine; @@ -132,7 +130,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe public static final String EXTRA_VIDEO_DOWNLOAD_URL = "EVDU"; public static final String EXTRA_SUBREDDIT = "ES"; public static final String EXTRA_ID = "EI"; - public static final String EXTRA_POST_TITLE = "EPT"; + public static final String EXTRA_POST = "EP"; public static final String EXTRA_PROGRESS_SECONDS = "EPS"; public static final String EXTRA_VIDEO_TYPE = "EVT"; public static final String EXTRA_GFYCAT_ID = "EGI"; @@ -163,17 +161,19 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe @BindView(R.id.progress_bar_view_video_activity) ProgressBar progressBar; @BindView(R.id.mute_exo_playback_control_view) - ImageButton muteButton; + MaterialButton muteButton; @BindView(R.id.hd_exo_playback_control_view) - ImageButton hdButton; + MaterialButton hdButton; @BindView(R.id.bottom_navigation_exo_playback_control_view) BottomAppBar bottomAppBar; @BindView(R.id.title_text_view_exo_playback_control_view) TextView titleTextView; + @BindView(R.id.back_button_exo_playback_control_view) + MaterialButton backButton; @BindView(R.id.download_image_view_exo_playback_control_view) - ImageView downloadImageView; + MaterialButton downloadButton; @BindView(R.id.playback_speed_image_view_exo_playback_control_view) - ImageView playbackSpeedImageView; + MaterialButton playbackSpeedButton; @BindView(R.id.lockable_nested_scroll_view_view_video_activity) LockableNestedScrollView nestedScrollView; @@ -301,6 +301,12 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe ButterKnife.bind(this); setVolumeControlStream(AudioManager.STREAM_MUSIC); + setTitle(" "); + + if (typeface != null) { + titleTextView.setTypeface(typeface); + } + Resources resources = getResources(); getWindow().getDecorView().setSystemUiVisibility( @@ -312,7 +318,11 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe if (useBottomAppBar) { getSupportActionBar().hide(); bottomAppBar.setVisibility(View.VISIBLE); - downloadImageView.setOnClickListener(view -> { + backButton.setOnClickListener(view -> { + finish(); + }); + + downloadButton.setOnClickListener(view -> { if (isDownloading) { return; } @@ -326,12 +336,8 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe requestPermissionAndDownload(); }); - playbackSpeedImageView.setOnClickListener(view -> { - PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); - playbackSpeedBottomSheetFragment.setArguments(bundle); - playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); + playbackSpeedButton.setOnClickListener(view -> { + changePlaybackSpeed(); }); } else { ActionBar actionBar = getSupportActionBar(); @@ -402,12 +408,15 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe }; orientationEventListener.enable(); } - } catch (Exception ignore) {} + } catch (Exception ignore) { + } } } - String postTitle = intent.getStringExtra(EXTRA_POST_TITLE); - setSmallTitle(postTitle); + Post post = intent.getParcelableExtra(EXTRA_POST); + if (post != null) { + titleTextView.setText(post.getTitle()); + } trackSelector = new DefaultTrackSelector(this); if (videoType == VIDEO_TYPE_NORMAL && isDataSavingMode && dataSavingModeDefaultResolution > 0) { @@ -598,20 +607,6 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe } } - private void setSmallTitle(String title) { - if (title != null) { - if (useBottomAppBar) { - titleTextView.setText(Html.fromHtml(String.format("%s", title))); - } else { - setTitle(Utils.getTabTextWithCustomFont(typeface, Html.fromHtml(String.format("%s", title)))); - } - } else { - if (!useBottomAppBar) { - setTitle(""); - } - } - } - private void preparePlayer(Bundle savedInstanceState) { if (mSharedPreferences.getBoolean(SharedPreferencesUtils.LOOP_VIDEO, true)) { player.setRepeatMode(Player.REPEAT_MODE_ALL); @@ -631,17 +626,17 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); if (isMute) { player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); + muteButton.setIconResource(R.drawable.ic_mute_24dp); } else { player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); + muteButton.setIconResource(R.drawable.ic_unmute_24dp); } } else if (muteVideo) { isMute = true; player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); + muteButton.setIconResource(R.drawable.ic_mute_24dp); } else { - muteButton.setImageResource(R.drawable.ic_unmute_24dp); + muteButton.setIconResource(R.drawable.ic_unmute_24dp); } player.addListener(new Player.Listener() { @@ -685,11 +680,11 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe if (isMute) { isMute = false; player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); + muteButton.setIconResource(R.drawable.ic_unmute_24dp); } else { isMute = true; player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); + muteButton.setIconResource(R.drawable.ic_mute_24dp); } }); } @@ -702,6 +697,14 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe }); } + private void changePlaybackSpeed() { + PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); + playbackSpeedBottomSheetFragment.setArguments(bundle); + playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); + } + private int inferPrimaryTrackType(Format format) { int trackType = MimeTypes.getTrackType(format.sampleMimeType); if (trackType != C.TRACK_TYPE_UNKNOWN) { @@ -884,7 +887,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe Toast.makeText(ViewVideoActivity.this, R.string.fetch_streamable_video_failed, Toast.LENGTH_SHORT).show(); return; } - setSmallTitle(streamableVideo.title); + titleTextView.setText(streamableVideo.title); progressBar.setVisibility(View.GONE); videoDownloadUrl = streamableVideo.mp4 == null ? streamableVideo.mp4Mobile.url : streamableVideo.mp4.url; mVideoUri = Uri.parse(videoDownloadUrl); @@ -939,11 +942,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe requestPermissionAndDownload(); return true; } else if (itemId == R.id.action_playback_speed_view_video_activity) { - PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); - playbackSpeedBottomSheetFragment.setArguments(bundle); - playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); + changePlaybackSpeed(); return true; } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageEmbeddedRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageEmbeddedRecyclerViewAdapter.java new file mode 100644 index 00000000..8d77856f --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageEmbeddedRecyclerViewAdapter.java @@ -0,0 +1,76 @@ +package eu.toldi.infinityforlemmy.adapters; + +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import eu.toldi.infinityforlemmy.R; +import eu.toldi.infinityforlemmy.activities.BaseActivity; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; +import eu.toldi.infinityforlemmy.databinding.ItemCommentFilterUsageEmbeddedBinding; + + +public class CommentFilterUsageEmbeddedRecyclerViewAdapter extends RecyclerView.Adapter { + private BaseActivity baseActivity; + private List commentFilterUsageList; + + public CommentFilterUsageEmbeddedRecyclerViewAdapter(BaseActivity baseActivity) { + this.baseActivity = baseActivity; + } + + @NonNull + @Override + public EntryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new EntryViewHolder(ItemCommentFilterUsageEmbeddedBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull EntryViewHolder holder, int position) { + if (commentFilterUsageList == null || commentFilterUsageList.isEmpty()) { + holder.textView.setText(R.string.comment_filter_applied_to_all_subreddits); + } else if (holder.getBindingAdapterPosition() > 4) { + holder.textView.setText(baseActivity.getString(R.string.comment_filter_usage_embedded_more_count, commentFilterUsageList.size() - 5)); + } else { + CommentFilterUsage commentFilterUsage = commentFilterUsageList.get(holder.getBindingAdapterPosition()); + switch (commentFilterUsage.usage) { + case CommentFilterUsage.SUBREDDIT_TYPE: + holder.textView.setText("r/" + commentFilterUsage.nameOfUsage); + break; + } + } + } + + @Override + public int getItemCount() { + return commentFilterUsageList == null || commentFilterUsageList.isEmpty() ? 1 : (commentFilterUsageList.size() > 5 ? 6 : commentFilterUsageList.size()); + } + + public void setCommentFilterUsageList(List commentFilterUsageList) { + this.commentFilterUsageList = commentFilterUsageList; + notifyDataSetChanged(); + } + + class EntryViewHolder extends RecyclerView.ViewHolder { + TextView textView; + + public EntryViewHolder(@NonNull ItemCommentFilterUsageEmbeddedBinding binding) { + super(binding.getRoot()); + textView = binding.getRoot(); + textView.setTextColor(baseActivity.customThemeWrapper.getSecondaryTextColor()); + + if (baseActivity.typeface != null) { + textView.setTypeface(baseActivity.typeface); + } + + textView.setOnClickListener(view -> { + Toast.makeText(baseActivity, textView.getText(), Toast.LENGTH_SHORT).show(); + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageRecyclerViewAdapter.java new file mode 100644 index 00000000..6c522c81 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterUsageRecyclerViewAdapter.java @@ -0,0 +1,80 @@ +package eu.toldi.infinityforlemmy.adapters; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import eu.toldi.infinityforlemmy.R; +import eu.toldi.infinityforlemmy.activities.BaseActivity; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; +import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; + + +public class CommentFilterUsageRecyclerViewAdapter extends RecyclerView.Adapter { + private List commentFilterUsages; + private BaseActivity activity; + private CustomThemeWrapper customThemeWrapper; + private CommentFilterUsageRecyclerViewAdapter.OnItemClickListener onItemClickListener; + + public interface OnItemClickListener { + void onClick(CommentFilterUsage commentFilterUsage); + } + + public CommentFilterUsageRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper, + CommentFilterUsageRecyclerViewAdapter.OnItemClickListener onItemClickListener) { + this.activity = activity; + this.customThemeWrapper = customThemeWrapper; + this.onItemClickListener = onItemClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new CommentFilterUsageRecyclerViewAdapter.CommentFilterUsageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_filter_usage, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + CommentFilterUsage commentFilterUsage = commentFilterUsages.get(position); + switch (commentFilterUsage.usage) { + case CommentFilterUsage.SUBREDDIT_TYPE: + ((CommentFilterUsageRecyclerViewAdapter.CommentFilterUsageViewHolder) holder).usageTextView.setText(activity.getString(R.string.post_filter_usage_community, commentFilterUsage.nameOfUsage)); + break; + } + } + + @Override + public int getItemCount() { + return commentFilterUsages == null ? 0 : commentFilterUsages.size(); + } + + public void setCommentFilterUsages(List commentFilterUsages) { + this.commentFilterUsages = commentFilterUsages; + notifyDataSetChanged(); + } + + private class CommentFilterUsageViewHolder extends RecyclerView.ViewHolder { + TextView usageTextView; + + public CommentFilterUsageViewHolder(@NonNull View itemView) { + super(itemView); + usageTextView = (TextView) itemView; + + usageTextView.setTextColor(customThemeWrapper.getPrimaryTextColor()); + + if (activity.typeface != null) { + usageTextView.setTypeface(activity.typeface); + } + + usageTextView.setOnClickListener(view -> { + onItemClickListener.onClick(commentFilterUsages.get(getBindingAdapterPosition())); + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterWithUsageRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterWithUsageRecyclerViewAdapter.java new file mode 100644 index 00000000..285c6523 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentFilterWithUsageRecyclerViewAdapter.java @@ -0,0 +1,81 @@ +package eu.toldi.infinityforlemmy.adapters; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import eu.toldi.infinityforlemmy.activities.BaseActivity; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterWithUsage; +import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; +import eu.toldi.infinityforlemmy.databinding.ItemCommentFilterWithUsageBinding; + + +public class CommentFilterWithUsageRecyclerViewAdapter extends RecyclerView.Adapter { + private BaseActivity activity; + private final OnItemClickListener onItemClickListener; + private List commentFilterWithUsageList; + private RecyclerView.RecycledViewPool recycledViewPool; + + public interface OnItemClickListener { + void onItemClick(CommentFilter commentFilter); + } + + public CommentFilterWithUsageRecyclerViewAdapter(BaseActivity activity, OnItemClickListener onItemClickListener) { + this.activity = activity; + this.recycledViewPool = new RecyclerView.RecycledViewPool(); + this.onItemClickListener = onItemClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new CommentFilterViewHolder(ItemCommentFilterWithUsageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof CommentFilterViewHolder) { + ((CommentFilterViewHolder) holder).binding.commentFilterNameTextViewItemCommentFilter.setText(commentFilterWithUsageList.get(position).commentFilter.name); + ((CommentFilterViewHolder) holder).adapter.setCommentFilterUsageList(commentFilterWithUsageList.get(position).commentFilterUsageList); + } + } + + @Override + public int getItemCount() { + return commentFilterWithUsageList == null ? 0 : commentFilterWithUsageList.size(); + } + + public void setCommentFilterWithUsageList(List commentFilterWithUsageList) { + this.commentFilterWithUsageList = commentFilterWithUsageList; + notifyDataSetChanged(); + } + + private class CommentFilterViewHolder extends RecyclerView.ViewHolder { + ItemCommentFilterWithUsageBinding binding; + CommentFilterUsageEmbeddedRecyclerViewAdapter adapter; + + public CommentFilterViewHolder(@NonNull ItemCommentFilterWithUsageBinding binding) { + super(binding.getRoot()); + this.binding = binding; + binding.commentFilterNameTextViewItemCommentFilter.setTextColor(activity.customThemeWrapper.getPrimaryTextColor()); + + if (activity.typeface != null) { + binding.commentFilterNameTextViewItemCommentFilter.setTypeface(activity.typeface); + } + + binding.getRoot().setOnClickListener(view -> { + onItemClickListener.onItemClick(commentFilterWithUsageList.get(getBindingAdapterPosition()).commentFilter); + }); + + binding.commentFilterUsageRecyclerViewItemCommentFilter.setRecycledViewPool(recycledViewPool); + binding.commentFilterUsageRecyclerViewItemCommentFilter.setLayoutManager(new LinearLayoutManagerBugFixed(activity)); + adapter = new CommentFilterUsageEmbeddedRecyclerViewAdapter(activity); + binding.commentFilterUsageRecyclerViewItemCommentFilter.setAdapter(adapter); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentsListingRecyclerViewAdapter.java index 0dd8492e..b573a0db 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/CommentsListingRecyclerViewAdapter.java @@ -4,7 +4,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.Color; -import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.text.Spanned; @@ -12,7 +11,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; @@ -26,6 +24,8 @@ import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.button.MaterialButton; + import java.util.Locale; import butterknife.BindView; @@ -49,6 +49,7 @@ import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; import eu.toldi.infinityforlemmy.customviews.SpoilerOnClickTextView; import eu.toldi.infinityforlemmy.customviews.SwipeLockInterface; import eu.toldi.infinityforlemmy.customviews.SwipeLockLinearLayoutManager; +import eu.toldi.infinityforlemmy.databinding.ItemCommentBinding; import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; import eu.toldi.infinityforlemmy.utils.APIUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; @@ -177,7 +178,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { @@ -517,20 +534,22 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { + upvoteButton.performClick(); + }); + downvoteButton.setOnClickListener(view -> { if (mAccessToken == null) { Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); @@ -588,19 +613,22 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter= mDepthThreshold) { - ((CommentViewHolder) holder).saveButton.setVisibility(View.GONE); - ((CommentViewHolder) holder).replyButton.setVisibility(View.GONE); + ((CommentBaseViewHolder) holder).saveButton.setVisibility(View.GONE); + ((CommentBaseViewHolder) holder).replyButton.setVisibility(View.GONE); } else { - ((CommentViewHolder) holder).saveButton.setVisibility(View.VISIBLE); - ((CommentViewHolder) holder).replyButton.setVisibility(View.VISIBLE); + ((CommentBaseViewHolder) holder).saveButton.setVisibility(View.VISIBLE); + ((CommentBaseViewHolder) holder).replyButton.setVisibility(View.VISIBLE); } if (comment.hasReply()) { if (comment.getChildCount() > 0 && (mAlwaysShowChildCommentCount || !comment.isExpanded())) { - ((CommentViewHolder) holder).expandButton.setText("+" + comment.getChildCount()); + ((CommentBaseViewHolder) holder).expandButton.setText("+" + comment.getChildCount()); } if (comment.isExpanded()) { - ((CommentViewHolder) holder).expandButton.setCompoundDrawablesWithIntrinsicBounds(collapseDrawable, null, null, null); + ((CommentBaseViewHolder) holder).expandButton.setCompoundDrawablesWithIntrinsicBounds(collapseDrawable, null, null, null); } else { - ((CommentViewHolder) holder).expandButton.setCompoundDrawablesWithIntrinsicBounds(expandDrawable, null, null, null); + ((CommentBaseViewHolder) holder).expandButton.setCompoundDrawablesWithIntrinsicBounds(expandDrawable, null, null, null); } - ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); + ((CommentBaseViewHolder) holder).expandButton.setVisibility(View.VISIBLE); } switch (comment.getVoteType()) { case Comment.VOTE_TYPE_UPVOTE: - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); - ((CommentViewHolder) holder).topScoreTextView.setTextColor(mUpvotedColor); - ((CommentViewHolder) holder).downvoteTextView.setTextColor(mCommentIconAndInfoColor); + ((CommentBaseViewHolder) holder).upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp); + ((CommentBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor)); + ((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + ((CommentBaseViewHolder) holder).topScoreTextView.setTextColor(mUpvotedColor); + ((CommentBaseViewHolder) holder).downvoteTextView.setTextColor(mCommentIconAndInfoColor); break; case Comment.VOTE_TYPE_DOWNVOTE: - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); - if(mSeperateUpandDownvote) { - ((CommentViewHolder) holder).downvoteTextView.setTextColor(mDownvotedColor); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); + ((CommentBaseViewHolder) holder).downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp); + ((CommentBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor)); + if (mSeperateUpandDownvote) { + ((CommentBaseViewHolder) holder).downvoteTextView.setTextColor(mDownvotedColor); + ((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); } else { - ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + ((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); } - ((CommentViewHolder) holder).topScoreTextView.setTextColor(mDownvotedColor); + ((CommentBaseViewHolder) holder).topScoreTextView.setTextColor(mDownvotedColor); break; default: - ((CommentViewHolder) holder).downvoteTextView.setTextColor(mCommentIconAndInfoColor); + ((CommentBaseViewHolder) holder).downvoteTextView.setTextColor(mCommentIconAndInfoColor); } if (mPost.isArchived()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - PorterDuff.Mode.SRC_IN); + ((CommentBaseViewHolder) holder).replyButton.setIconTint(ColorStateList.valueOf(mVoteAndReplyUnavailableVoteButtonColor)); + ((CommentBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mVoteAndReplyUnavailableVoteButtonColor)); + ((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mVoteAndReplyUnavailableVoteButtonColor); + ((CommentBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mVoteAndReplyUnavailableVoteButtonColor)); } if (mPost.isLocked()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - PorterDuff.Mode.SRC_IN); + ((CommentBaseViewHolder) holder).replyButton.setIconTint(ColorStateList.valueOf(mVoteAndReplyUnavailableVoteButtonColor)); } if (comment.isSaved()) { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + ((CommentBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp); } else { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + ((CommentBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); } if (position == mSearchCommentIndex) { @@ -661,7 +654,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter expandedComments, Integer parentId, ArrayList children) { if (parentComment.getId() == mVisibleComments.get(parentPosition).getId()) { @@ -818,7 +811,6 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter authorTextView.performClick()); @@ -1454,20 +1466,23 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { + upvoteButton.performClick(); + }); + + downvoteTextView.setOnClickListener(view -> { + downvoteButton.performClick(); + }); + downvoteButton.setOnClickListener(view -> { if (mPost.isArchived()) { Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); @@ -1556,17 +1582,19 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter 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_GALLERY_TYPE = 3; - private static final int VIEW_TYPE_POST_CARD_TEXT_TYPE = 4; - private static final int VIEW_TYPE_POST_COMPACT = 5; - private static final int VIEW_TYPE_POST_GALLERY = 6; - private static final int VIEW_TYPE_POST_GALLERY_GALLERY_TYPE = 7; - private static final int VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE = 8; - private static final int VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE = 9; - private static final int VIEW_TYPE_POST_CARD_2_GALLERY_TYPE = 10; - private static final int VIEW_TYPE_POST_CARD_2_TEXT_TYPE = 11; - - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull Post post, @NonNull Post t1) { - return post.getId() == 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 retrofit; - private Retrofit mGfycatRetrofit; - private Retrofit mRedgifsRetrofit; - private Provider mStreamableApiProvider; - 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 mModeratorColor; - 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; - private RecyclerView.RecycledViewPool mGalleryRecycledViewPool; - - public HistoryPostRecyclerViewAdapter(BaseActivity activity, HistoryPostFragment fragment, Executor executor, Retrofit oauthRetrofit, - Retrofit gfycatRetrofit, Retrofit redgifsRetrofit, Provider streambleApiProvider, - CustomThemeWrapper customThemeWrapper, Locale locale, - String accessToken, String accountName, int postType, int postLayout, boolean displaySubredditName, - SharedPreferences sharedPreferences, - SharedPreferences nsfwAndSpoilerSharedPreferences, - ExoCreator exoCreator, Callback callback) { - super(DIFF_CALLBACK); - if (activity != null) { - mActivity = activity; - mFragment = fragment; - mSharedPreferences = sharedPreferences; - mExecutor = executor; - retrofit = oauthRetrofit; - mGfycatRetrofit = gfycatRetrofit; - mRedgifsRetrofit = redgifsRetrofit; - mStreamableApiProvider = streambleApiProvider; - 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(); - mModeratorColor = customThemeWrapper.getModerator(); - 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 = AppCompatResources.getDrawable(activity, R.drawable.ic_comment_grey_24dp); - if (mCommentIcon != null) { - mCommentIcon.setTint(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; - mGalleryRecycledViewPool = new RecyclerView.RecycledViewPool(); - } - } - - 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())) { - 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: - return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; - case Post.GALLERY_TYPE: - return VIEW_TYPE_POST_CARD_GALLERY_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) { - Post post = getItem(position); - if (post != null) { - if (post.getPostType() == Post.GALLERY_TYPE) { - return VIEW_TYPE_POST_GALLERY_GALLERY_TYPE; - } else { - return VIEW_TYPE_POST_GALLERY; - } - } else { - 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())) { - 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: - return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; - case Post.GALLERY_TYPE: - return VIEW_TYPE_POST_CARD_2_GALLERY_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_GALLERY_TYPE) { - return new PostGalleryTypeViewHolder(ItemPostGalleryTypeBinding.inflate(LayoutInflater.from(parent.getContext()), 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_GALLERY_GALLERY_TYPE) { - return new PostGalleryGalleryTypeViewHolder(ItemPostGalleryGalleryTypeBinding.inflate(LayoutInflater.from(parent.getContext()), 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 if (viewType == VIEW_TYPE_POST_CARD_2_GALLERY_TYPE) { - return new PostCard2GalleryTypeViewHolder(ItemPostCard2GalleryTypeBinding.inflate(LayoutInflater.from(parent.getContext()), 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); - } - - ((PostBaseViewHolder) holder).userTextView.setTextColor( - post.isModerator() ? mModeratorColor : mUsernameColor); - - 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); - } - - } - }); - } 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.isAuthorDeleted() ? post.getSubredditName() : post.getAuthor(); - mFragment.loadIcon(authorName, post.isAuthorDeleted(), (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); - } - - 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.isFeaturedInCommunity() || post.isFeaturedOnInstance()) { - ((PostBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostBaseViewHolder) holder).stickiedPostImageView); - if (post.isFeaturedOnInstance()) { - ((PostBaseViewHolder) holder).stickiedPostImageView.setColorFilter(mModeratorColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - } - - 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 (!((PostVideoAutoplayViewHolder) holder).isManuallyPaused) { - 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.create(GfycatAPI.class).getGfycatData(post.getGfycatId()) : - mRedgifsRetrofit.create(RedgifsAPI.class).getRedgifsData(post.getGfycatId()); - FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), - ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall, - 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 = - mStreamableApiProvider.get().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); - } - } - - 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 (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)))) { - ((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 (holder instanceof PostBaseGalleryTypeViewHolder) { - if (mDataSavingMode && mDisableImagePreview) { - ((PostBaseGalleryTypeViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); - ((PostBaseGalleryTypeViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); - } else { - ((PostBaseGalleryTypeViewHolder) holder).frameLayout.setVisibility(View.VISIBLE); - ((PostBaseGalleryTypeViewHolder) holder).imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, 1, post.getGallery().size())); - Post.Preview preview = getSuitablePreview(post.getPreviews()); - if (preview != null) { - if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { - ((PostBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); - } else { - ((PostBaseGalleryTypeViewHolder) holder).adapter.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); - } - } else { - ((PostBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); - } - ((PostBaseGalleryTypeViewHolder) holder).adapter.setGalleryImages(post.getGallery()); - ((PostBaseGalleryTypeViewHolder) holder).adapter.setBlurImage( - (post.isNSFW() && mNeedBlurNsfw) ); - } - } else if (holder instanceof PostTextTypeViewHolder) { - if (!mHideTextPostContent && 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 (!((PostCard2VideoAutoplayViewHolder) holder).isManuallyPaused) { - 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.create(GfycatAPI.class).getGfycatData(post.getGfycatId()) : - mRedgifsRetrofit.create(RedgifsAPI.class).getRedgifsData(post.getGfycatId()); - FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), - ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall, - 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 = - mStreamableApiProvider.get().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); - } - } - - 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 (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)))) { - ((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 (holder instanceof PostCard2TextTypeViewHolder) { - if (!mHideTextPostContent && 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 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); - } - - } - }); - } 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.isAuthorDeleted() ? post.getSubredditName() : post.getAuthor(); - mFragment.loadIcon(authorName, post.isAuthorDeleted(), (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( - post.isModerator() ? mModeratorColor : 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); - } - - 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.isFeaturedInCommunity()) { - ((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: { - 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); - - 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); - } - ((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)))) { - ((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: { - 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_outline_video_24dp); - } - break; - } - case Post.LINK_TYPE: { - 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_link_post_type_indicator)); - - 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; - } - } - } - } else if (holder instanceof PostGalleryBaseGalleryTypeViewHolder) { - Post post = getItem(position); - if (post != null) { - ((PostGalleryBaseGalleryTypeViewHolder) holder).post = post; - ((PostGalleryBaseGalleryTypeViewHolder) holder).currentPosition = position; - - if (mDataSavingMode && mDisableImagePreview) { - ((PostGalleryBaseGalleryTypeViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); - ((PostGalleryBaseGalleryTypeViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); - } else { - Post.Preview preview = getSuitablePreview(post.getPreviews()); - ((PostGalleryBaseGalleryTypeViewHolder) holder).preview = preview; - - ((PostGalleryBaseGalleryTypeViewHolder) holder).frameLayout.setVisibility(View.VISIBLE); - ((PostGalleryBaseGalleryTypeViewHolder) holder).imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, 1, post.getGallery().size())); - if (preview != null) { - if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { - ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); - } else { - ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); - } - } else { - ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); - } - ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setGalleryImages(post.getGallery()); - ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setBlurImage( - (post.isNSFW() && mNeedBlurNsfw) ); - } - } - } - } - - @Nullable - private Post.Preview getSuitablePreview(ArrayList 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)); - if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { - url = post.getUrl(); - } else { - url = preview.getPreviewUrl(); - } - RequestBuilder 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 previews = post.getPreviews(); - if (previews != null && !previews.isEmpty()) { - if (previews.size() >= 2) { - postCompactThumbnailPreviewUrl = previews.get(1).getPreviewUrl(); - } else { - postCompactThumbnailPreviewUrl = previews.get(0).getPreviewUrl(); - } - - RequestBuilder imageRequestBuilder = mGlide.load(postCompactThumbnailPreviewUrl) - .error(R.drawable.ic_error_outline_black_24dp).listener(((PostCompactBaseViewHolder) holder).requestListener); - if ((post.isNSFW() && mNeedBlurNsfw)) { - 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)); - if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { - url = post.getUrl(); - } else { - url = preview.getPreviewUrl(); - } - RequestBuilder 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)); - if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { - url = post.getUrl(); - } else { - url = preview.getPreviewUrl(); - } - RequestBuilder 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 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); - if (!((PostVideoAutoplayViewHolder) holder).isManuallyPaused) { - ((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 PostBaseGalleryTypeViewHolder) { - ((PostBaseGalleryTypeViewHolder) holder).frameLayout.setVisibility(View.GONE); - ((PostBaseGalleryTypeViewHolder) holder).noPreviewImageView.setVisibility(View.GONE); - ((PostBaseGalleryTypeViewHolder) holder).adapter.setGalleryImages(null); - } 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); - } else if (holder instanceof PostGalleryBaseGalleryTypeViewHolder) { - holder.itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); - ((PostGalleryBaseGalleryTypeViewHolder) holder).frameLayout.setVisibility(View.GONE); - ((PostGalleryBaseGalleryTypeViewHolder) 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) { - openMedia(post, 0); - } - - private void openMedia(Post post, int galleryItemIndex) { - 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()); - intent.putExtra(ViewRedditGalleryActivity.EXTRA_GALLERY_ITEM_INDEX, galleryItemIndex); - 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()); - } - } - }); - - itemView.setOnTouchListener((v, event) -> { - if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { - if (mFragment.isRecyclerViewItemSwipeable(PostBaseViewHolder.this)) { - mActivity.unlockSwipeRightToGoBack(); - } - } else { - if (mFragment.isRecyclerViewItemSwipeable(PostBaseViewHolder.this)) { - mActivity.lockSwipeRightToGoBack(); - } - } - return false; - }); - - userTextView.setOnClickListener(view -> { - if (canStartActivity) { - int position = getBindingAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post == null || post.isAuthorDeleted()) { - return; - } - 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); - }); - } - - 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(); - int newVoteType; - - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != 1) { - //Not upvoted before - post.setVoteType(1); - newVoteType = Integer.parseInt(APIUtils.DIR_UPVOTE); - upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - post.setVoteType(0); - newVoteType = Integer.parseInt(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.votePost(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - int currentPosition = getBindingAdapterPosition(); - if (newVoteType == Integer.parseInt(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.getId(), 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(); - int newVoteType; - - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != -1) { - //Not downvoted before - post.setVoteType(-1); - newVoteType = Integer.parseInt(APIUtils.DIR_DOWNVOTE); - downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - //Downvoted before - post.setVoteType(0); - newVoteType = Integer.parseInt(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.votePost(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - int currentPosition = getBindingAdapterPosition(); - if (newVoteType == Integer.parseInt(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.getId(), 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; - } - SavePost savePost = new SavePost(); - if (post.isSaved()) { - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - savePost.unsaveThing(retrofit, mAccessToken, post.getId(), - 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); - savePost.saveThing(retrofit, mAccessToken, post.getId(), - 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); - } - }); - - shareButton.setOnLongClickListener(view -> { - int position = getBindingAdapterPosition(); - if (position < 0) { - return false; - } - Post post = getItem(position); - if (post != null) { - mActivity.copyLink(post.getPermalink()); - return true; - } - return false; - }); - } - - 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.exo_pause) - ImageView pauseButton; - @BindView(R.id.exo_play) - ImageView playButton; - @BindView(R.id.exo_progress) - DefaultTimeBar progressBar; - @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 - Container container; - @Nullable - ExoPlayerViewHelper helper; - private Uri mediaUri; - private float volume; - public Call fetchGfycatOrStreamableVideoCall; - private boolean isManuallyPaused; - - 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); - } - } - }); - - pauseButton.setOnClickListener(view -> { - pause(); - isManuallyPaused = true; - savePlaybackInfo(getPlayerOrder(), getCurrentPlaybackInfo()); - }); - - playButton.setOnClickListener(view -> { - isManuallyPaused = false; - play(); - }); - - progressBar.addListener(new TimeBar.OnScrubListener() { - @Override - public void onScrubStart(TimeBar timeBar, long position) { - - } - - @Override - public void onScrubMove(TimeBar timeBar, long position) { - - } - - @Override - public void onScrubStop(TimeBar timeBar, long position, boolean canceled) { - if (!canceled) { - savePlaybackInfo(getPlayerOrder(), getCurrentPlaybackInfo()); - } - } - }); - - 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; - } - - private void savePlaybackInfo(int order, @Nullable PlaybackInfo playbackInfo) { - if (container != null) container.savePlaybackInfo(order, playbackInfo); - } - - @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 (this.container == null) { - this.container = container; - } - if (helper == null) { - helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); - helper.addEventListener(new Playable.DefaultEventListener() { - @Override - public void onTracksChanged(@NonNull Tracks tracks) { - ImmutableList trackGroups = tracks.getGroups(); - if (!trackGroups.isEmpty()) { - for (int i = 0; i < trackGroups.size(); i++) { - String mimeType = trackGroups.get(i).getTrackFormat(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) { - if (!isPlaying() && isManuallyPaused) { - helper.play(); - pause(); - helper.setVolume(volume); - } else { - 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; - } - isManuallyPaused = false; - container = 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 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 target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorTextView.setVisibility(View.VISIBLE); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - errorTextView.setVisibility(View.GONE); - progressBar.setVisibility(View.GONE); - return false; - } - }; - } - } - - public class PostBaseGalleryTypeViewHolder extends PostBaseViewHolder { - FrameLayout frameLayout; - RecyclerView galleryRecyclerView; - CustomTextView imageIndexTextView; - ImageView noPreviewImageView; - - PostGalleryTypeImageRecyclerViewAdapter adapter; - private boolean swipeLocked; - - PostBaseGalleryTypeViewHolder(View rootView, - 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, - FrameLayout frameLayout, - RecyclerView galleryRecyclerView, - CustomTextView imageIndexTextView, - ImageView noPreviewImageView, - ConstraintLayout bottomConstraintLayout, - ImageView upvoteButton, - TextView scoreTextView, - ImageView downvoteButton, - TextView commentsCountTextView, - ImageView saveButton, - ImageView shareButton, - boolean itemViewIsNotCardView) { - super(rootView); - setBaseView( - iconGifImageView, - subredditTextView, - userTextView, - stickiedPostImageView, - postTimeTextView, - titleTextView, - typeTextView, - archivedImageView, - lockedImageView, - crosspostImageView, - nsfwTextView, - spoilerTextView, - flairTextView, - awardsTextView, - bottomConstraintLayout, - upvoteButton, - scoreTextView, - downvoteButton, - commentsCountTextView, - saveButton, - shareButton, - itemViewIsNotCardView); - - this.frameLayout = frameLayout; - this.galleryRecyclerView = galleryRecyclerView; - this.imageIndexTextView = imageIndexTextView; - this.noPreviewImageView = noPreviewImageView; - - imageIndexTextView.setTextColor(mMediaIndicatorIconTint); - imageIndexTextView.setBackgroundColor(mMediaIndicatorBackgroundColor); - imageIndexTextView.setBorderColor(mMediaIndicatorBackgroundColor); - if (mActivity.typeface != null) { - imageIndexTextView.setTypeface(mActivity.typeface); - } - - noPreviewImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); - noPreviewImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); - - adapter = new PostGalleryTypeImageRecyclerViewAdapter(mGlide, mActivity.typeface, - mSaveMemoryCenterInsideDownsampleStrategy, mColorAccent, mPrimaryTextColor, mScale); - galleryRecyclerView.setOnTouchListener((v, motionEvent) -> { - if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP || motionEvent.getActionMasked() == MotionEvent.ACTION_CANCEL) { - if (mActivity.mSliderPanel != null) { - mActivity.mSliderPanel.requestDisallowInterceptTouchEvent(false); - } - - if (mActivity.mViewPager2 != null) { - mActivity.mViewPager2.setUserInputEnabled(true); - } - mActivity.unlockSwipeRightToGoBack(); - swipeLocked = false; - } else { - if (mActivity.mSliderPanel != null) { - mActivity.mSliderPanel.requestDisallowInterceptTouchEvent(true); - } - if (mActivity.mViewPager2 != null) { - mActivity.mViewPager2.setUserInputEnabled(false); - } - mActivity.lockSwipeRightToGoBack(); - swipeLocked = true; - } - - return false; - }); - galleryRecyclerView.setAdapter(adapter); - new PagerSnapHelper().attachToRecyclerView(galleryRecyclerView); - galleryRecyclerView.setRecycledViewPool(mGalleryRecycledViewPool); - LinearLayoutManagerBugFixed layoutManager = new LinearLayoutManagerBugFixed(mActivity, RecyclerView.HORIZONTAL, false); - galleryRecyclerView.setLayoutManager(layoutManager); - galleryRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - } - - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, layoutManager.findFirstVisibleItemPosition() + 1, post.getGallery().size())); - } - }); - galleryRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { - private float downX; - private float downY; - private boolean dragged; - private final int minTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop(); - - @Override - public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { - int action = e.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - downX = e.getRawX(); - downY = e.getRawY(); - break; - case MotionEvent.ACTION_MOVE: - if(Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) { - dragged = true; - } - break; - case MotionEvent.ACTION_UP: - if (!dragged) { - int position = getBindingAdapterPosition(); - if (position >= 0) { - if (post != null) { - openMedia(post, layoutManager.findFirstVisibleItemPosition()); - } - } - } - - downX = 0; - downY = 0; - dragged = false; - } - return false; - } - - @Override - public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { - - } - - @Override - public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { - - } - }); - - noPreviewImageView.setOnClickListener(view -> { - int position = getBindingAdapterPosition(); - if (position < 0) { - return; - } - if (post != null) { - openMedia(post, 0); - } - }); - } - - public boolean isSwipeLocked() { - return swipeLocked; - } - } - - public class PostGalleryTypeViewHolder extends PostBaseGalleryTypeViewHolder { - - PostGalleryTypeViewHolder(ItemPostGalleryTypeBinding binding) { - super(binding.getRoot(), - binding.iconGifImageViewItemPostGalleryType, - binding.subredditNameTextViewItemPostGalleryType, - binding.userTextViewItemPostGalleryType, - binding.stickiedPostImageViewItemPostGalleryType, - binding.postTimeTextViewItemPostGalleryType, - binding.titleTextViewItemPostGalleryType, - binding.typeTextViewItemPostGalleryType, - binding.archivedImageViewItemPostGalleryType, - binding.lockedImageViewItemPostGalleryType, - binding.crosspostImageViewItemPostGalleryType, - binding.nsfwTextViewItemPostGalleryType, - binding.spoilerTextViewItemPostGalleryType, - binding.flairTextViewItemPostGalleryType, - binding.awardsTextViewItemPostGalleryType, - binding.galleryFrameLayoutItemPostGalleryType, - binding.galleryRecyclerViewItemPostGalleryType, - binding.imageIndexTextViewItemPostGalleryType, - binding.noPreviewImageViewItemPostGalleryType, - binding.bottomConstraintLayoutItemPostGalleryType, - binding.upvoteButtonItemPostGalleryType, - binding.scoreTextViewItemPostGalleryType, - binding.downvoteButtonItemPostGalleryType, - binding.commentsCountTextViewItemPostGalleryType, - binding.saveButtonItemPostGalleryType, - binding.shareButtonItemPostGalleryType, - 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 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; - }); - - itemView.setOnTouchListener((v, event) -> { - if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { - if (mFragment.isRecyclerViewItemSwipeable(PostCompactBaseViewHolder.this)) { - mActivity.unlockSwipeRightToGoBack(); - } - } else { - if (mFragment.isRecyclerViewItemSwipeable(PostCompactBaseViewHolder.this)) { - mActivity.lockSwipeRightToGoBack(); - } - } - return false; - }); - - 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 if (!post.isAuthorDeleted()) { - 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); - }); - - 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(); - int newVoteType; - - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != 1) { - //Not upvoted before - post.setVoteType(1); - newVoteType = Integer.parseInt(APIUtils.DIR_UPVOTE); - upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - post.setVoteType(0); - newVoteType = Integer.parseInt(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.votePost(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - int currentPosition = getBindingAdapterPosition(); - if (newVoteType == Integer.parseInt(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.getId(), 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(); - int newVoteType; - - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != -1) { - //Not downvoted before - post.setVoteType(-1); - newVoteType = Integer.parseInt(APIUtils.DIR_DOWNVOTE); - downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - //Downvoted before - post.setVoteType(0); - newVoteType = Integer.parseInt(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.votePost(mActivity, retrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - int currentPosition = getBindingAdapterPosition(); - if (newVoteType == Integer.parseInt(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.getId(), 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) { - SavePost savePost = new SavePost(); - if (post.isSaved()) { - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - savePost.unsaveThing(retrofit, mAccessToken, post.getId(), - 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); - savePost.saveThing(retrofit, mAccessToken, post.getId(), - 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); - } - }); - - shareButton.setOnLongClickListener(view -> { - int position = getBindingAdapterPosition(); - if (position < 0) { - return false; - } - Post post = getItem(position); - if (post != null) { - mActivity.copyLink(post.getPermalink()); - return true; - } - return false; - }); - - requestListener = new RequestListener<>() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target 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 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 target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorTextView.setVisibility(View.VISIBLE); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - errorTextView.setVisibility(View.GONE); - progressBar.setVisibility(View.GONE); - return false; - } - }; - } - } - - class PostGalleryBaseGalleryTypeViewHolder extends RecyclerView.ViewHolder { - - FrameLayout frameLayout; - RecyclerView recyclerView; - CustomTextView imageIndexTextView; - ImageView noPreviewImageView; - - PostGalleryTypeImageRecyclerViewAdapter adapter; - private LinearLayoutManagerBugFixed layoutManager; - - Post post; - Post.Preview preview; - - int currentPosition; - - public PostGalleryBaseGalleryTypeViewHolder(@NonNull View itemView, - FrameLayout frameLayout, - RecyclerView recyclerView, - CustomTextView imageIndexTextView, - ImageView noPreviewImageView) { - super(itemView); - - this.frameLayout = frameLayout; - this.recyclerView = recyclerView; - this.imageIndexTextView = imageIndexTextView; - this.noPreviewImageView = noPreviewImageView; - - if (mActivity.typeface != null) { - imageIndexTextView.setTypeface(mActivity.typeface); - } - - itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); - noPreviewImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); - noPreviewImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); - - imageIndexTextView.setTextColor(mMediaIndicatorIconTint); - imageIndexTextView.setBackgroundColor(mMediaIndicatorBackgroundColor); - imageIndexTextView.setBorderColor(mMediaIndicatorBackgroundColor); - - adapter = new PostGalleryTypeImageRecyclerViewAdapter(mGlide, mActivity.typeface, - mSaveMemoryCenterInsideDownsampleStrategy, mColorAccent, mPrimaryTextColor, mScale); - recyclerView.setOnTouchListener((v, motionEvent) -> { - if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP || motionEvent.getActionMasked() == MotionEvent.ACTION_CANCEL) { - if (mActivity.mSliderPanel != null) { - mActivity.mSliderPanel.requestDisallowInterceptTouchEvent(false); - } - if (mActivity.mViewPager2 != null) { - mActivity.mViewPager2.setUserInputEnabled(true); - } - mActivity.unlockSwipeRightToGoBack(); - } else { - if (mActivity.mSliderPanel != null) { - mActivity.mSliderPanel.requestDisallowInterceptTouchEvent(true); - } - if (mActivity.mViewPager2 != null) { - mActivity.mViewPager2.setUserInputEnabled(false); - } - mActivity.lockSwipeRightToGoBack(); - } - - return false; - }); - recyclerView.setAdapter(adapter); - new PagerSnapHelper().attachToRecyclerView(recyclerView); - recyclerView.setRecycledViewPool(mGalleryRecycledViewPool); - layoutManager = new LinearLayoutManagerBugFixed(mActivity, RecyclerView.HORIZONTAL, false); - recyclerView.setLayoutManager(layoutManager); - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - } - - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, layoutManager.findFirstVisibleItemPosition() + 1, post.getGallery().size())); - } - }); - recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { - private float downX; - private float downY; - private boolean dragged; - private long downTime; - private final int minTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop(); - private final int longClickThreshold = ViewConfiguration.getLongPressTimeout(); - - @Override - public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { - int action = e.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - downX = e.getRawX(); - downY = e.getRawY(); - downTime = System.currentTimeMillis(); - break; - case MotionEvent.ACTION_MOVE: - if(Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) { - dragged = true; - } - if (!dragged) { - if (System.currentTimeMillis() - downTime >= longClickThreshold) { - onLongClick(); - } - } - break; - case MotionEvent.ACTION_UP: - if (!dragged) { - if (System.currentTimeMillis() - downTime < longClickThreshold) { - onClick(); - } - } - case MotionEvent.ACTION_CANCEL: - downX = 0; - downY = 0; - dragged = false; - - } - return false; - } - - @Override - public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { - - } - - @Override - public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { - - } - }); - - noPreviewImageView.setOnClickListener(view -> { - onClick(); - }); - - noPreviewImageView.setOnLongClickListener(view -> onLongClick()); - } - - void onClick() { - 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, layoutManager.findFirstVisibleItemPosition()); - } - } - } - } - - boolean onLongClick() { - 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, layoutManager.findFirstVisibleItemPosition()); - } - } - } - - return true; - } - } - - class PostGalleryGalleryTypeViewHolder extends PostGalleryBaseGalleryTypeViewHolder { - - public PostGalleryGalleryTypeViewHolder(@NonNull ItemPostGalleryGalleryTypeBinding binding) { - super(binding.getRoot(), binding.galleryFrameLayoutItemPostGalleryGalleryType, - binding.galleryRecyclerViewItemPostGalleryGalleryType, binding.imageIndexTextViewItemPostGalleryGalleryType, - binding.imageViewNoPreviewItemPostGalleryGalleryType); - } - } - - 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.exo_pause) - ImageView pauseButton; - @BindView(R.id.exo_play) - ImageView playButton; - @BindView(R.id.exo_progress) - DefaultTimeBar progressBar; - @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 - Container container; - @Nullable - ExoPlayerViewHelper helper; - private Uri mediaUri; - private float volume; - public Call fetchGfycatOrStreamableVideoCall; - private boolean isManuallyPaused; - - 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); - } - } - }); - - pauseButton.setOnClickListener(view -> { - pause(); - isManuallyPaused = true; - savePlaybackInfo(getPlayerOrder(), getCurrentPlaybackInfo()); - }); - - playButton.setOnClickListener(view -> { - isManuallyPaused = false; - play(); - }); - - progressBar.addListener(new TimeBar.OnScrubListener() { - @Override - public void onScrubStart(TimeBar timeBar, long position) { - - } - - @Override - public void onScrubMove(TimeBar timeBar, long position) { - - } - - @Override - public void onScrubStop(TimeBar timeBar, long position, boolean canceled) { - if (!canceled) { - savePlaybackInfo(getPlayerOrder(), getCurrentPlaybackInfo()); - } - } - }); - - 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; - } - - private void savePlaybackInfo(int order, @Nullable PlaybackInfo playbackInfo) { - if (container != null) container.savePlaybackInfo(order, playbackInfo); - } - - @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 (this.container == null) { - this.container = container; - } - if (helper == null) { - helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); - helper.addEventListener(new Playable.DefaultEventListener() { - @Override - public void onTracksChanged(@NonNull Tracks tracks) { - ImmutableList trackGroups = tracks.getGroups(); - if (!trackGroups.isEmpty()) { - for (int i = 0; i < trackGroups.size(); i++) { - String mimeType = trackGroups.get(i).getTrackFormat(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) { - if (!isPlaying() && isManuallyPaused) { - helper.play(); - pause(); - helper.setVolume(volume); - } else { - 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; - } - isManuallyPaused = false; - container = 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 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 target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorTextView.setVisibility(View.VISIBLE); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - errorTextView.setVisibility(View.GONE); - progressBar.setVisibility(View.GONE); - return false; - } - }; - } - } - - public class PostCard2GalleryTypeViewHolder extends PostBaseGalleryTypeViewHolder { - - PostCard2GalleryTypeViewHolder(ItemPostCard2GalleryTypeBinding binding) { - super(binding.getRoot(), - binding.iconGifImageViewItemPostCard2GalleryType, - binding.subredditNameTextViewItemPostCard2GalleryType, - binding.userTextViewItemPostCard2GalleryType, - binding.stickiedPostImageViewItemPostCard2GalleryType, - binding.postTimeTextViewItemPostCard2GalleryType, - binding.titleTextViewItemPostCard2GalleryType, - binding.typeTextViewItemPostCard2GalleryType, - binding.archivedImageViewItemPostCard2GalleryType, - binding.lockedImageViewItemPostCard2GalleryType, - binding.crosspostImageViewItemPostCard2GalleryType, - binding.nsfwTextViewItemPostCard2GalleryType, - binding.spoilerCustomTextViewItemPostCard2GalleryType, - binding.flairCustomTextViewItemPostCard2GalleryType, - binding.awardsTextViewItemPostCard2GalleryType, - binding.galleryFrameLayoutItemPostCard2GalleryType, - binding.galleryRecyclerViewItemPostCard2GalleryType, - binding.imageIndexTextViewItemPostCard2GalleryType, - binding.noPreviewImageViewItemPostCard2GalleryType, - binding.bottomConstraintLayoutItemPostCard2GalleryType, - binding.upvoteButtonItemPostCard2GalleryType, - binding.scoreTextViewItemPostCard2GalleryType, - binding.downvoteButtonItemPostCard2GalleryType, - binding.commentsCountTextViewItemPostCard2GalleryType, - binding.saveButtonItemPostCard2GalleryType, - binding.shareButtonItemPostCard2GalleryType, - true); - - binding.dividerItemPostCard2GalleryType.setBackgroundColor(mDividerColor); - } - } - - 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/eu/toldi/infinityforlemmy/adapters/PostDetailRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/PostDetailRecyclerViewAdapter.java index e9f890d2..634a75d4 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/PostDetailRecyclerViewAdapter.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/PostDetailRecyclerViewAdapter.java @@ -8,7 +8,6 @@ import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; -import android.graphics.ColorFilter; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -21,10 +20,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; -import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -51,6 +47,7 @@ import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.DefaultTimeBar; import com.google.android.exoplayer2.ui.PlayerView; import com.google.android.exoplayer2.ui.TimeBar; +import com.google.android.material.button.MaterialButton; import com.google.common.collect.ImmutableList; import com.libRG.CustomTextView; @@ -61,8 +58,7 @@ import java.util.regex.Pattern; import javax.inject.Provider; -import butterknife.BindView; -import butterknife.ButterKnife; + import eu.toldi.infinityforlemmy.FetchGfycatOrRedgifsVideoLinks; import eu.toldi.infinityforlemmy.FetchStreamableVideo; import eu.toldi.infinityforlemmy.R; @@ -96,6 +92,14 @@ import eu.toldi.infinityforlemmy.customviews.AspectRatioGifImageView; import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; import eu.toldi.infinityforlemmy.customviews.SwipeLockInterface; import eu.toldi.infinityforlemmy.customviews.SwipeLockLinearLayoutManager; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailGalleryBinding; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailImageAndGifAutoplayBinding; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailLinkBinding; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailNoPreviewBinding; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailTextBinding; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailVideoAndGifPreviewBinding; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailVideoAutoplayBinding; +import eu.toldi.infinityforlemmy.databinding.ItemPostDetailVideoAutoplayLegacyControllerBinding; import eu.toldi.infinityforlemmy.fragments.ViewPostDetailFragment; import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; import eu.toldi.infinityforlemmy.post.Post; @@ -444,47 +448,52 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { @@ -492,13 +501,13 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter= 0) { @@ -511,11 +520,11 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter() { @@ -679,8 +689,8 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter transition) { int width = resource.getIntrinsicWidth(); int height = resource.getIntrinsicHeight(); - ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) width / height); - ((PostDetailVideoAutoplayViewHolder) holder).previewImageView.setImageDrawable(resource); + ((PostDetailBaseVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) width / height); + ((PostDetailBaseVideoAutoplayViewHolder) holder).previewImageView.setImageDrawable(resource); } @Override @@ -689,18 +699,18 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadImageProgressBar.setVisibility(View.GONE); - ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.VISIBLE); - ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadImageErrorTextView.setOnClickListener(view -> { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadImageProgressBar.setVisibility(View.VISIBLE); - ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.GONE); + ((PostDetailImageAndGifAutoplayViewHolder) holder).binding.progressBarItemPostDetailImageAndGifAutoplay.setVisibility(View.GONE); + ((PostDetailImageAndGifAutoplayViewHolder) holder).binding.loadImageErrorTextViewItemPostDetailImageAndGifAutoplay.setVisibility(View.VISIBLE); + ((PostDetailImageAndGifAutoplayViewHolder) holder).binding.loadImageErrorTextViewItemPostDetailImageAndGifAutoplay.setOnClickListener(view -> { + ((PostDetailImageAndGifAutoplayViewHolder) holder).binding.progressBarItemPostDetailImageAndGifAutoplay.setVisibility(View.VISIBLE); + ((PostDetailImageAndGifAutoplayViewHolder) holder).binding.loadImageErrorTextViewItemPostDetailImageAndGifAutoplay.setVisibility(View.GONE); loadImage(holder, preview); }); return false; @@ -889,7 +899,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter target, DataSource dataSource, boolean isFirstResource) { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); + ((PostDetailImageAndGifAutoplayViewHolder) holder).binding.loadWrapperItemPostDetailImageAndGifAutoplay.setVisibility(View.GONE); return false; } }); @@ -901,17 +911,17 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - ((PostDetailVideoAndGifPreviewHolder) holder).mLoadImageProgressBar.setVisibility(View.GONE); - ((PostDetailVideoAndGifPreviewHolder) holder).mLoadImageErrorTextView.setVisibility(View.VISIBLE); - ((PostDetailVideoAndGifPreviewHolder) holder).mLoadImageErrorTextView.setOnClickListener(view -> { - ((PostDetailVideoAndGifPreviewHolder) holder).mLoadImageProgressBar.setVisibility(View.VISIBLE); - ((PostDetailVideoAndGifPreviewHolder) holder).mLoadImageErrorTextView.setVisibility(View.GONE); + ((PostDetailVideoAndGifPreviewHolder) holder).binding.progressBarItemPostDetailVideoAndGifPreview.setVisibility(View.GONE); + ((PostDetailVideoAndGifPreviewHolder) holder).binding.loadImageErrorTextViewItemPostDetailVideoAndGifPreview.setVisibility(View.VISIBLE); + ((PostDetailVideoAndGifPreviewHolder) holder).binding.loadImageErrorTextViewItemPostDetailVideoAndGifPreview.setOnClickListener(view -> { + ((PostDetailVideoAndGifPreviewHolder) holder).binding.progressBarItemPostDetailVideoAndGifPreview.setVisibility(View.VISIBLE); + ((PostDetailVideoAndGifPreviewHolder) holder).binding.loadImageErrorTextViewItemPostDetailVideoAndGifPreview.setVisibility(View.GONE); loadImage(holder, preview); }); return false; @@ -952,7 +962,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter target, DataSource dataSource, boolean isFirstResource) { - ((PostDetailVideoAndGifPreviewHolder) holder).mLoadWrapper.setVisibility(View.GONE); + ((PostDetailVideoAndGifPreviewHolder) holder).binding.loadWrapperItemPostDetailVideoAndGifPreview.setVisibility(View.GONE); return false; } }); @@ -965,17 +975,17 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - ((PostDetailLinkViewHolder) holder).mLoadImageProgressBar.setVisibility(View.GONE); - ((PostDetailLinkViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.VISIBLE); - ((PostDetailLinkViewHolder) holder).mLoadImageErrorTextView.setOnClickListener(view -> { - ((PostDetailLinkViewHolder) holder).mLoadImageProgressBar.setVisibility(View.VISIBLE); - ((PostDetailLinkViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.GONE); + ((PostDetailLinkViewHolder) holder).binding.progressBarItemPostDetailLink.setVisibility(View.GONE); + ((PostDetailLinkViewHolder) holder).binding.loadImageErrorTextViewItemPostDetailLink.setVisibility(View.VISIBLE); + ((PostDetailLinkViewHolder) holder).binding.loadImageErrorTextViewItemPostDetailLink.setOnClickListener(view -> { + ((PostDetailLinkViewHolder) holder).binding.progressBarItemPostDetailLink.setVisibility(View.VISIBLE); + ((PostDetailLinkViewHolder) holder).binding.loadImageErrorTextViewItemPostDetailLink.setVisibility(View.GONE); loadImage(holder, preview); }); return false; @@ -1016,7 +1026,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter target, DataSource dataSource, boolean isFirstResource) { - ((PostDetailLinkViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); + ((PostDetailLinkViewHolder) holder).binding.loadWrapperItemPostDetailLink.setVisibility(View.GONE); return false; } }); @@ -1029,20 +1039,20 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter transition) { int width = resource.getIntrinsicWidth(); int height = resource.getIntrinsicHeight(); - ((PostDetailLinkViewHolder) holder).mImageView.setImageDrawable(resource); + ((PostDetailLinkViewHolder) holder).binding.imageViewItemPostDetailLink.setImageDrawable(resource); if (preview.getPreviewHeight() == 0 || preview.getPreviewWidth() == 0) { - ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) height / width); - ((PostDetailLinkViewHolder) holder).mImageView.getLayoutParams().height = height; + ((PostDetailLinkViewHolder) holder).binding.imageViewItemPostDetailLink.setRatio((float) height / width); + ((PostDetailLinkViewHolder) holder).binding.imageViewItemPostDetailLink.getLayoutParams().height = height; preview.setPreviewHeight(height); preview.setPreviewWidth(width); } else { - ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + ((PostDetailLinkViewHolder) holder).binding.imageViewItemPostDetailLink.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); } } @Override public void onLoadCleared(@Nullable Drawable placeholder) { - ((PostDetailLinkViewHolder) holder).mImageView.setImageDrawable(null); + ((PostDetailLinkViewHolder) holder).binding.imageViewItemPostDetailLink.setImageDrawable(null); } }); } @@ -1098,15 +1108,15 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter mSubredditTextView.performClick()); + iconGifImageView.setOnClickListener(view -> subredditTextView.performClick()); View.OnClickListener communityClickListener = view -> { Intent intent; @@ -1280,7 +1291,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { @@ -1292,19 +1303,19 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter mUserTextView.performClick()); + authorFlairTextView.setOnClickListener(view -> userTextView.performClick()); - mCrosspostImageView.setOnClickListener(view -> { + crosspostImageView.setOnClickListener(view -> { Intent crosspostIntent = new Intent(mActivity, ViewPostDetailActivity.class); crosspostIntent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, mPost.getCrosspostParentId()); mActivity.startActivity(crosspostIntent); }); if (!mHidePostType) { - mTypeTextView.setOnClickListener(view -> { + typeTextView.setOnClickListener(view -> { Intent intent = new Intent(mActivity, FilteredPostsActivity.class); intent.putExtra(FilteredPostsActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, PostPagingSource.TYPE_SUBREDDIT); @@ -1312,13 +1323,13 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + nSFWTextView.setOnClickListener(view -> { Intent intent = new Intent(mActivity, FilteredPostsActivity.class); intent.putExtra(FilteredPostsActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, PostPagingSource.TYPE_SUBREDDIT); @@ -1326,7 +1337,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + upvoteButton.setOnClickListener(view -> { if (mPost.isArchived()) { Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); return; @@ -1349,38 +1360,43 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + scoreTextView.setOnClickListener(view -> { + upvoteButton.performClick(); + }); + + downvoteButton.setOnClickListener(view -> { if (mPost.isArchived()) { Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); return; @@ -1451,31 +1478,36 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + this.commentsCountButton.setOnClickListener(view -> { if (mPost.isArchived()) { Toast.makeText(mActivity, R.string.archived_post_comment_unavailable, Toast.LENGTH_SHORT).show(); return; @@ -1578,23 +1616,23 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + this.saveButton.setOnClickListener(view -> { if (mAccessToken == null) { Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); return; } SavePost savePost = new SavePost(); if (mPost.isSaved()) { - mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + this.saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); savePost.unsaveThing(mRetrofit.getRetrofit(), mAccessToken, mPost.getId(), new SaveThing.SaveThingListener() { @Override public void success() { mPost.setSaved(false); - mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + PostDetailBaseViewHolder.this.saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); Toast.makeText(mActivity, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } @@ -1602,19 +1640,19 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + this.shareButton.setOnClickListener(view -> { String link = (mShareOnLocalInstance) ? mRetrofit.getBaseURL() + "/post/" + mPost.getId() : mPost.getPermalink(); Bundle bundle = new Bundle(); bundle.putString(ShareLinkBottomSheetFragment.EXTRA_POST_LINK, link); @@ -1653,7 +1691,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + this.shareButton.setOnLongClickListener(view -> { String link = (mShareOnLocalInstance) ? mRetrofit.getBaseURL() + "/post/" + mPost.getId() : mPost.getPermalink(); mActivity.copyLink(link); return true; @@ -1661,158 +1699,94 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter fetchGfycatOrStreamableVideoCall; - @BindView(R.id.icon_gif_image_view_item_post_detail_video_autoplay) - AspectRatioGifImageView mIconGifImageView; - @BindView(R.id.subreddit_text_view_item_post_detail_video_autoplay) - TextView mSubredditTextView; - - @BindView(R.id.community_instance_text_view_item_post_detail_video_autoplay) - TextView mCommunityInstanceTextView; - @BindView(R.id.user_text_view_item_post_detail_video_autoplay) - TextView mUserTextView; - @BindView(R.id.user_instance_text_view_item_post_detail_video_autoplay) - TextView mUserInstanceTextView; - - @BindView(R.id.author_flair_text_view_item_post_detail_video_autoplay) - TextView mAuthorFlairTextView; - @BindView(R.id.post_time_text_view_item_post_detail_video_autoplay) - TextView mPostTimeTextView; - @BindView(R.id.title_text_view_item_post_detail_video_autoplay) - TextView mTitleTextView; - @BindView(R.id.type_text_view_item_post_detail_video_autoplay) - CustomTextView mTypeTextView; - @BindView(R.id.crosspost_image_view_item_post_detail_video_autoplay) - ImageView mCrosspostImageView; - @BindView(R.id.archived_image_view_item_post_detail_video_autoplay) - ImageView mArchivedImageView; - @BindView(R.id.locked_image_view_item_post_detail_video_autoplay) - ImageView mLockedImageView; - @BindView(R.id.nsfw_text_view_item_post_detail_video_autoplay) - CustomTextView mNSFWTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_detail_video_autoplay) - CustomTextView mSpoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_detail_video_autoplay) - CustomTextView mFlairTextView; - @BindView(R.id.awards_text_view_item_post_detail_video_autoplay) - TextView mAwardsTextView; - @BindView(R.id.upvote_ratio_text_view_item_post_detail_video_autoplay) - TextView mUpvoteRatioTextView; - @BindView(R.id.aspect_ratio_frame_layout_item_post_detail_video_autoplay) AspectRatioFrameLayout aspectRatioFrameLayout; - @BindView(R.id.player_view_item_post_detail_video_autoplay) PlayerView playerView; - @BindView(R.id.preview_image_view_item_post_detail_video_autoplay) GifImageView previewImageView; - @BindView(R.id.error_loading_gfycat_image_view_item_post_detail_video_autoplay) ImageView mErrorLoadingGfycatImageView; - @BindView(R.id.mute_exo_playback_control_view) ImageView muteButton; - @BindView(R.id.fullscreen_exo_playback_control_view) ImageView fullscreenButton; - @BindView(R.id.exo_pause) ImageView pauseButton; - @BindView(R.id.exo_play) ImageView playButton; - @BindView(R.id.exo_progress) DefaultTimeBar progressBar; - @BindView(R.id.content_markdown_view_item_post_detail_video_autoplay) - RecyclerView mContentMarkdownView; - @BindView(R.id.bottom_constraint_layout_item_post_detail_video_autoplay) - ConstraintLayout mBottomConstraintLayout; - @BindView(R.id.plus_button_item_post_detail_video_autoplay) - ImageView mUpvoteButton; - @BindView(R.id.score_text_view_item_post_detail_video_autoplay) - TextView mScoreTextView; - - @BindView(R.id.downvote_text_view_item_post_detail_video_autoplay) - TextView mDownvoteTextView; - @BindView(R.id.minus_button_item_post_detail_video_autoplay) - ImageView mDownvoteButton; - @BindView(R.id.comments_count_item_post_detail_video_autoplay) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_detail_video_autoplay) - ImageView mSaveButton; - @BindView(R.id.share_button_item_post_detail_video_autoplay) - ImageView mShareButton; @Nullable Container container; @Nullable @@ -1821,46 +1795,87 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { if (helper != null) { if (helper.getVolume() != 0) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_24dp)); + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_24dp)); helper.setVolume(0f); volume = 0f; } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_24dp)); + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_24dp)); helper.setVolume(1f); volume = 1f; } @@ -1897,7 +1912,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + binding.imageViewItemPostDetailVideoAndGifPreview.setOnClickListener(view -> { if (canStartActivity) { canStartActivity = false; if (mPost.getPostType() == Post.VIDEO_TYPE) { @@ -2180,7 +2209,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + binding.imageViewItemPostDetailImageAndGifAutoplay.setOnClickListener(view -> { if (canStartActivity) { canStartActivity = false; if (mPost.getPostType() == Post.IMAGE_TYPE) { @@ -2321,110 +2288,46 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + binding.imageViewItemPostDetailLink.setOnClickListener(view -> { Intent intent = new Intent(mActivity, LinkResolverActivity.class); Uri uri = Uri.parse(mPost.getUrl()); intent.setData(uri); @@ -2435,102 +2338,46 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + binding.imageViewNoPreviewPostTypeItemPostDetailNoPreview.setOnClickListener(view -> { if (mPost != null) { if (mPost.getPostType() == Post.VIDEO_TYPE) { Intent intent = new Intent(mActivity, ViewVideoActivity.class); @@ -2549,7 +2396,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + binding.galleryRecyclerViewItemPostDetailGallery.setAdapter(adapter); + new PagerSnapHelper().attachToRecyclerView(binding.galleryRecyclerViewItemPostDetailGallery); + binding.galleryRecyclerViewItemPostDetailGallery.setOnTouchListener((v, motionEvent) -> { if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP || motionEvent.getActionMasked() == MotionEvent.ACTION_CANCEL) { if (mActivity.mSliderPanel != null) { mActivity.mSliderPanel.requestDisallowInterceptTouchEvent(false); @@ -2715,8 +2503,8 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + binding.noPreviewPostTypeImageViewItemPostDetailGallery.setOnClickListener(view -> { Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class); intent.putParcelableArrayListExtra(ViewRedditGalleryActivity.EXTRA_REDDIT_GALLERY, mPost.getGallery()); intent.putExtra(ViewRedditGalleryActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); @@ -2790,89 +2578,37 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { +public class PostFilterWithUsageRecyclerViewAdapter extends RecyclerView.Adapter { private static final int VIEW_TYPE_HEADER = 1; private static final int VIEW_TYPE_POST_FILTER = 2; @@ -24,16 +28,18 @@ public class PostFilterRecyclerViewAdapter extends RecyclerView.Adapter postFilterList; + private List postFilterWithUsageList; + private RecyclerView.RecycledViewPool recycledViewPool; public interface OnItemClickListener { void onItemClick(PostFilter postFilter); } - public PostFilterRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper, - OnItemClickListener onItemClickListener) { + public PostFilterWithUsageRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper, + OnItemClickListener onItemClickListener) { this.activity = activity; this.customThemeWrapper = customThemeWrapper; + this.recycledViewPool = new RecyclerView.RecycledViewPool(); this.onItemClickListener = onItemClickListener; } @@ -51,43 +57,49 @@ public class PostFilterRecyclerViewAdapter extends RecyclerView.Adapter postFilterList) { - this.postFilterList = postFilterList; + public void setPostFilterWithUsageList(List postFilterWithUsageList) { + this.postFilterWithUsageList = postFilterWithUsageList; notifyDataSetChanged(); } private class PostFilterViewHolder extends RecyclerView.ViewHolder { - TextView textView; + ItemPostFilterWithUsageBinding binding; + PostFilterUsageEmbeddedRecyclerViewAdapter adapter; - public PostFilterViewHolder(@NonNull View itemView) { - super(itemView); - textView = (TextView) itemView; - - textView.setTextColor(customThemeWrapper.getPrimaryTextColor()); + public PostFilterViewHolder(@NonNull ItemPostFilterWithUsageBinding binding) { + super(binding.getRoot()); + this.binding = binding; + binding.postFilterNameTextViewItemPostFilter.setTextColor(customThemeWrapper.getPrimaryTextColor()); if (activity.typeface != null) { - textView.setTypeface(activity.typeface); + binding.postFilterNameTextViewItemPostFilter.setTypeface(activity.typeface); } - itemView.setOnClickListener(view -> { - onItemClickListener.onItemClick(postFilterList.get(getBindingAdapterPosition() - 1)); + binding.getRoot().setOnClickListener(view -> { + onItemClickListener.onItemClick(postFilterWithUsageList.get(getBindingAdapterPosition() - 1).postFilter); }); + + binding.postFilterUsageRecyclerViewItemPostFilter.setRecycledViewPool(recycledViewPool); + binding.postFilterUsageRecyclerViewItemPostFilter.setLayoutManager(new LinearLayoutManagerBugFixed(activity)); + adapter = new PostFilterUsageEmbeddedRecyclerViewAdapter(activity); + binding.postFilterUsageRecyclerViewItemPostFilter.setAdapter(adapter); } } @@ -100,4 +112,4 @@ public class PostFilterRecyclerViewAdapter extends RecyclerView.Adapter DIFF_CALLBACK = new DiffUtil.ItemCallback() { @Override @@ -167,6 +187,8 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter() { @@ -756,15 +848,15 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter transition) { int width = resource.getIntrinsicWidth(); int height = resource.getIntrinsicHeight(); - ((PostVideoAutoplayViewHolder) holder).previewImageView.setImageDrawable(resource); + ((PostBaseVideoAutoplayViewHolder) holder).previewImageView.setImageDrawable(resource); if (preview.getPreviewHeight() <= 0 || preview.getPreviewWidth() <= 0) { - ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) height / width); - ((PostVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = height; + ((PostBaseVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) height / width); + ((PostBaseVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = height; preview.setPreviewHeight(height); preview.setPreviewWidth(width); } else { - ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); - ((PostVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = preview.getPreviewHeight(); + ((PostBaseVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + ((PostBaseVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = preview.getPreviewHeight(); } } @@ -774,22 +866,22 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter() { @@ -950,13 +1042,13 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { + 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(((PostMaterial3CardBaseViewHolder) 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(((PostMaterial3CardBaseViewHolder) 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(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostMaterial3CardBaseViewHolder) 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(((PostMaterial3CardBaseViewHolder) 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(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getBindingAdapterPosition() >= 0) { + //post.getCommunityInfo().setIcon() ... + } + } + }); + } 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(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + } + } + } else { + if (post.getAuthorIconUrl() == null) { + String authorName = post.isAuthorDeleted() ? post.getSubredditName() : post.getAuthor(); + mFragment.loadIcon(authorName, post.isAuthorDeleted(), (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(((PostMaterial3CardBaseViewHolder) 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(((PostMaterial3CardBaseViewHolder) 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(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + } + } + + if (mShowElapsedTime) { + ((PostMaterial3CardBaseViewHolder) holder).postTimeTextView.setText( + Utils.getElapsedTime(mActivity, post.getPostTimeMillis())); + } else { + ((PostMaterial3CardBaseViewHolder) holder).postTimeTextView.setText(Utils.getFormattedTime(mLocale, post.getPostTimeMillis(), mTimeFormatPattern)); + } + + ((PostMaterial3CardBaseViewHolder) holder).titleTextView.setText(post.getTitle()); + if (!mHideTheNumberOfVotes) { + ((PostMaterial3CardBaseViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } else { + ((PostMaterial3CardBaseViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.vote)); + } + + switch (post.getVoteType()) { + case 1: + //Upvoted + ((PostMaterial3CardBaseViewHolder) holder).upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp); + ((PostMaterial3CardBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor)); + ((PostMaterial3CardBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + break; + case -1: + //Downvoted + ((PostMaterial3CardBaseViewHolder) holder).downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp); + ((PostMaterial3CardBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor)); + ((PostMaterial3CardBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + break; + } + + if (mPostType == PostPagingSource.TYPE_SUBREDDIT && !mDisplaySubredditName && (post.isFeaturedInCommunity() || post.isFeaturedOnInstance())) { + ((PostMaterial3CardBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostMaterial3CardBaseViewHolder) holder).stickiedPostImageView); + } + + if (post.isArchived()) { + ((PostMaterial3CardBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mVoteAndReplyUnavailableVoteButtonColor)); + ((PostMaterial3CardBaseViewHolder) holder).scoreTextView.setTextColor(mVoteAndReplyUnavailableVoteButtonColor); + ((PostMaterial3CardBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mVoteAndReplyUnavailableVoteButtonColor)); + } + + if (!mHideTheNumberOfComments) { + ((PostMaterial3CardBaseViewHolder) holder).commentsCountButton.setVisibility(View.VISIBLE); + ((PostMaterial3CardBaseViewHolder) holder).commentsCountButton.setText(Integer.toString(post.getNComments())); + } else { + ((PostMaterial3CardBaseViewHolder) holder).commentsCountButton.setVisibility(View.GONE); + } + + if (post.isSaved()) { + ((PostMaterial3CardBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((PostMaterial3CardBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); + } + + if (holder instanceof PostMaterial3CardBaseVideoAutoplayViewHolder) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); + Post.Preview preview = getSuitablePreview(post.getPreviews()); + if (!mFixedHeightPreviewInCard && preview != null) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); + mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).previewImageView); + } else { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); + } + if (!((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).isManuallyPaused) { + if (mFragment.getMasterMutingOption() == null) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + } else { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).setVolume(mFragment.getMasterMutingOption() ? 0f : 1f); + } + } + + if ((post.isGfycat() || post.isRedgifs()) && !post.isLoadGfycatOrStreamableVideoSuccess()) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = + post.isGfycat() ? mGfycatRetrofit.create(GfycatAPI.class).getGfycatData(post.getGfycatId()) : + mRedgifsRetrofit.create(RedgifsAPI.class).getRedgifsData(post.getGfycatId()); + FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall, + 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()) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } + + @Override + public void failed(int errorCode) { + if (position == holder.getBindingAdapterPosition()) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + } + }); + } else if (post.isStreamable() && !post.isLoadGfycatOrStreamableVideoSuccess()) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = + mStreamableApiProvider.get().getStreamableData(post.getStreamableShortCode()); + FetchStreamableVideo.fetchStreamableVideoInRecyclerViewAdapter(mExecutor, new Handler(), + ((PostMaterial3CardBaseVideoAutoplayViewHolder) 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()) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } + + @Override + public void failed() { + if (position == holder.getBindingAdapterPosition()) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + } + }); + } else { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } else if (holder instanceof PostMaterial3CardWithPreviewViewHolder) { + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.VISIBLE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + } else if (post.getPostType() == Post.GIF_TYPE) { + if (!mAutoplay) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.VISIBLE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); + } + } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.linkTextViewItemPostCard3WithPreview.setVisibility(View.VISIBLE); + String domain = Uri.parse(post.getUrl()).getHost(); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.linkTextViewItemPostCard3WithPreview.setText(domain); + if (post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setVisibility(View.VISIBLE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_link); + } + } + + if (post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.progressBarItemPostCard3WithPreview.setVisibility(View.VISIBLE); + } + + if (mDataSavingMode && mDisableImagePreview) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_image_24dp); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_link); + } + } else if (mDataSavingMode && mOnlyDisablePreviewInVideoAndGifPosts && (post.getPostType() == Post.VIDEO_TYPE || post.getPostType() == Post.GIF_TYPE)) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setVisibility(View.VISIBLE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.GONE); + } else { + if (post.getPostType() == Post.GIF_TYPE && ((post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(mAutoplay && mAutoplayNsfwVideos)))) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setVisibility(View.VISIBLE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_image_24dp); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.GONE); + } else { + Post.Preview preview = getSuitablePreview(post.getPreviews()); + ((PostMaterial3CardWithPreviewViewHolder) holder).preview = preview; + if (preview != null) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview.setVisibility(View.VISIBLE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageWrapperRelativeLayoutItemPostCard3WithPreview.setVisibility(View.VISIBLE); + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + int height = (int) (400 * mScale); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview.getLayoutParams().height = height; + } else { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview.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) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview.removeOnLayoutChangeListener(this); + loadImage(holder); + } + }); + } else { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_image_24dp); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_link); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setImageResource(R.drawable.ic_gallery_24dp); + } + } + } + } + } else if (holder instanceof PostMaterial3CardBaseGalleryTypeViewHolder) { + if (mDataSavingMode && mDisableImagePreview) { + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + } else { + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).frameLayout.setVisibility(View.VISIBLE); + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, 1, post.getGallery().size())); + Post.Preview preview = getSuitablePreview(post.getPreviews()); + if (preview != null) { + if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); + } else { + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).adapter.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + } else { + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); + } + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).adapter.setGalleryImages(post.getGallery()); + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).adapter.setBlurImage( + (post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()))); + } + } else if (holder instanceof PostMaterial3CardTextTypeViewHolder) { + if (!mHideTextPostContent && post.getSelfTextPlainTrimmed() != null && !post.getSelfTextPlainTrimmed().equals("")) { + ((PostMaterial3CardTextTypeViewHolder) holder).binding.contentTextViewItemPostCard3TextType.setVisibility(View.VISIBLE); + if (post.isRead()) { + ((PostMaterial3CardTextTypeViewHolder) holder).binding.contentTextViewItemPostCard3TextType.setTextColor(mReadPostContentColor); + } + ((PostMaterial3CardTextTypeViewHolder) holder).binding.contentTextViewItemPostCard3TextType.setText(post.getSelfTextPlainTrimmed()); + } + } + mCallback.currentlyBindItem(holder.getBindingAdapterPosition()); + } } } @@ -1645,66 +2095,66 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter() { @Override public void onLoadStarted(@Nullable Drawable placeholder) { - ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).binding.progressBarItemPostWithPreview.setVisibility(View.VISIBLE); } @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { - ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setImageDrawable(resource); int height = resource.getIntrinsicHeight(); if (!mFixedHeightPreviewInCard) { float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); - ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(imageRatio); - ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setRatio(imageRatio); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setImageDrawable(resource); } else { - ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(-1); - ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = height; + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setRatio(-1); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.getLayoutParams().height = height; } - ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.VISIBLE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).binding.progressBarItemPostWithPreview.setVisibility(View.GONE); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // Reset to default aspect ratio - ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(1); - ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(placeholder); - ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setRatio(1); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setImageDrawable(placeholder); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).binding.progressBarItemPostWithPreview.setVisibility(View.VISIBLE); } }); } else { imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget() { @Override public void onLoadStarted(@Nullable Drawable placeholder) { - ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).binding.progressBarItemPostWithPreview.setVisibility(View.VISIBLE); } @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { - ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setImageDrawable(resource); int height = resource.getIntrinsicHeight(); if (!mFixedHeightPreviewInCard) { float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); - ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(imageRatio); - ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setRatio(imageRatio); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setImageDrawable(resource); } else { - ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(-1); - ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = height; + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setRatio(-1); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.getLayoutParams().height = height; } - ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.VISIBLE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).binding.progressBarItemPostWithPreview.setVisibility(View.GONE); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // Reset to default aspect ratio - ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(1); - ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(placeholder); - ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setRatio(1); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setImageDrawable(placeholder); + ((PostWithPreviewTypeViewHolder) holder).binding.imageViewItemPostWithPreview.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).binding.progressBarItemPostWithPreview.setVisibility(View.VISIBLE); } }); } @@ -1829,68 +2279,89 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter() { @Override public void onLoadStarted(@Nullable Drawable placeholder) { - ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).binding.progressBarItemPostCard2WithPreview.setVisibility(View.VISIBLE); } @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { - ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setImageDrawable(resource); int height = resource.getIntrinsicHeight(); if (!mFixedHeightPreviewInCard) { float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); - ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(imageRatio); - ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setRatio(imageRatio); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setImageDrawable(resource); } else { - ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(-1); - ((PostCard2WithPreviewViewHolder) holder).imageView.getLayoutParams().height = height; + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setRatio(-1); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.getLayoutParams().height = height; } - ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.VISIBLE); - ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).binding.progressBarItemPostCard2WithPreview.setVisibility(View.GONE); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // Reset to default aspect ratio - ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(1); - ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(placeholder); - ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setRatio(1); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setImageDrawable(placeholder); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).binding.progressBarItemPostCard2WithPreview.setVisibility(View.VISIBLE); } }); } else { imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget() { @Override public void onLoadStarted(@Nullable Drawable placeholder) { - ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).binding.progressBarItemPostCard2WithPreview.setVisibility(View.VISIBLE); } @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { - ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setImageDrawable(resource); int height = resource.getIntrinsicHeight(); if (!mFixedHeightPreviewInCard) { float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); - ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(imageRatio); - ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setRatio(imageRatio); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setImageDrawable(resource); } else { - ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(-1); - ((PostCard2WithPreviewViewHolder) holder).imageView.getLayoutParams().height = height; + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setRatio(-1); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.getLayoutParams().height = height; } - ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.VISIBLE); - ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).binding.progressBarItemPostCard2WithPreview.setVisibility(View.GONE); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // Reset to default aspect ratio - ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(1); - ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(placeholder); - ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); - ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setRatio(1); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setImageDrawable(placeholder); + ((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview.setVisibility(View.GONE); + ((PostCard2WithPreviewViewHolder) holder).binding.progressBarItemPostCard2WithPreview.setVisibility(View.VISIBLE); } }); + imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostCard2WithPreviewViewHolder) holder).binding.imageViewItemPostCard2WithPreview); + } + } + } else if (holder instanceof PostMaterial3CardWithPreviewViewHolder) { + Post post = ((PostMaterial3CardWithPreviewViewHolder) holder).post; + Post.Preview preview = ((PostMaterial3CardWithPreviewViewHolder) holder).preview; + if (preview != null) { + String url; + boolean blurImage = (post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(post.getPostType() == Post.GIF_TYPE && mAutoplay && mAutoplayNsfwVideos)); + if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { + url = post.getUrl(); + } else { + url = preview.getPreviewUrl(); + } + RequestBuilder imageRequestBuilder = mGlide.load(url).listener(((PostMaterial3CardWithPreviewViewHolder) holder).glideRequestListener); + + if (blurImage) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) + .into(((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview); + } else { + imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview); } } } @@ -2073,59 +2544,59 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter= 0) { + Post post = getItem(position); + ((PostMaterial3CardBaseViewHolder) holder).markPostRead(post, false); + } + } + holder.itemView.setBackgroundTintList(ColorStateList.valueOf(mFilledCardViewBackgroundColor)); + mGlide.clear(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + ((PostMaterial3CardBaseViewHolder) holder).titleTextView.setTextColor(mPostTitleColor); + if (holder instanceof PostMaterial3CardBaseVideoAutoplayViewHolder) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).mediaUri = null; + if (((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall != null && !((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall.isCanceled()) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall.cancel(); + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = null; + } + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.GONE); + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); + if (!((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).isManuallyPaused) { + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).resetVolume(); + } + mGlide.clear(((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).previewImageView); + ((PostMaterial3CardBaseVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); + } else if (holder instanceof PostMaterial3CardWithPreviewViewHolder) { + mGlide.clear(((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewItemPostCard3WithPreview.setVisibility(View.GONE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageWrapperRelativeLayoutItemPostCard3WithPreview.setVisibility(View.GONE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.loadImageErrorTextViewItemPostCard3WithPreview.setVisibility(View.GONE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setVisibility(View.GONE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.progressBarItemPostCard3WithPreview.setVisibility(View.GONE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setVisibility(View.GONE); + ((PostMaterial3CardWithPreviewViewHolder) holder).binding.linkTextViewItemPostCard3WithPreview.setVisibility(View.GONE); + } else if (holder instanceof PostMaterial3CardBaseGalleryTypeViewHolder) { + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).frameLayout.setVisibility(View.GONE); + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).noPreviewImageView.setVisibility(View.GONE); + ((PostMaterial3CardBaseGalleryTypeViewHolder) holder).adapter.setGalleryImages(null); + } else if (holder instanceof PostMaterial3CardTextTypeViewHolder) { + ((PostMaterial3CardTextTypeViewHolder) holder).binding.contentTextViewItemPostCard3TextType.setText(""); + ((PostMaterial3CardTextTypeViewHolder) holder).binding.contentTextViewItemPostCard3TextType.setTextColor(mPostContentColor); + ((PostMaterial3CardTextTypeViewHolder) holder).binding.contentTextViewItemPostCard3TextType.setVisibility(View.GONE); + } + + mGlide.clear(((PostMaterial3CardBaseViewHolder) holder).iconGifImageView); + ((PostMaterial3CardBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.GONE); + ((PostMaterial3CardBaseViewHolder) holder).upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); + ((PostMaterial3CardBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + ((PostMaterial3CardBaseViewHolder) holder).scoreTextView.setTextColor(mPostIconAndInfoColor); + ((PostMaterial3CardBaseViewHolder) holder).downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); + ((PostMaterial3CardBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); } } @@ -2306,7 +2831,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { int position = getBindingAdapterPosition(); @@ -2635,28 +3159,32 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { + upvoteButton.performClick(); + }); + downvoteButton.setOnClickListener(view -> { int position = getBindingAdapterPosition(); if (position < 0) { @@ -2746,32 +3283,36 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter itemView.performClick()); + saveButton.setOnClickListener(view -> { int position = getBindingAdapterPosition(); if (position < 0) { @@ -2859,14 +3407,14 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter fetchGfycatOrStreamableVideoCall; private boolean isManuallyPaused; - PostVideoAutoplayViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); + PostBaseVideoAutoplayViewHolder(View rootView, + AspectRatioGifImageView iconGifImageView, + TextView subredditTextView, + TextView communityInstanceTextView, + TextView userTextView, + TextView userInstanceTextView, + ImageView stickiedPostImageView, + TextView postTimeTextView, + TextView titleTextView, + CustomTextView typeTextView, + ImageView crosspostImageView, + ImageView archivedImageView, + ImageView lockedImageView, + CustomTextView nsfwTextView, + CustomTextView spoilerTextView, + CustomTextView flairTextView, + CustomTextView awardsTextView, + AspectRatioFrameLayout aspectRatioFrameLayout, + GifImageView previewImageView, + ImageView errorLoadingGfycatImageView, + PlayerView videoPlayer, + ImageView muteButton, + ImageView fullscreenButton, + ImageView pauseButton, + ImageView playButton, + DefaultTimeBar progressBar, + ConstraintLayout bottomConstraintLayout, + MaterialButton upvoteButton, + TextView scoreTextView, + TextView downvoteTextView, + MaterialButton downvoteButton, + MaterialButton commentsCountButton, + MaterialButton saveButton, + MaterialButton shareButton) { + super(rootView); setBaseView( iconGifImageView, subredditTextView, @@ -3094,21 +3614,31 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { if (helper != null) { if (helper.getVolume() != 0) { - muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_24dp)); helper.setVolume(0f); volume = 0f; mFragment.videoAutoplayChangeMutingOption(true); } else { - muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_24dp)); helper.setVolume(1f); volume = 1f; mFragment.videoAutoplayChangeMutingOption(false); @@ -3153,7 +3683,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter glideRequestListener; - PostWithPreviewTypeViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); + PostWithPreviewTypeViewHolder(@NonNull ItemPostWithPreviewBinding binding) { + super(binding.getRoot()); + this.binding = binding; setBaseView( - iconGifImageView, - subredditTextView, - communityInstanceTextView, - userTextView, - userInstanceTextView, - stickiedPostImageView, - postTimeTextView, - titleTextView, - typeTextView, - archivedImageView, - lockedImageView, - crosspostImageView, - nsfwTextView, - spoilerTextView, - flairTextView, - awardsTextView, - bottomConstraintLayout, - upvoteButton, - scoreTextView, - downvoteTextView, - downvoteButton, - commentsCountTextView, - saveButton, - shareButton); + binding.iconGifImageViewItemPostWithPreview, + binding.subredditNameTextViewItemPostWithPreview, + binding.communityInstanceTextViewItemPostWithPreview, + binding.userTextViewItemPostWithPreview, + binding.userInstanceTextViewItemPostWithPreview, + binding.stickiedPostImageViewItemPostWithPreview, + binding.postTimeTextViewItemPostWithPreview, + binding.titleTextViewItemPostWithPreview, + binding.typeTextViewItemPostWithPreview, + binding.archivedImageViewItemPostWithPreview, + binding.lockedImageViewItemPostWithPreview, + binding.crosspostImageViewItemPostWithPreview, + binding.nsfwTextViewItemPostWithPreview, + binding.spoilerCustomTextViewItemPostWithPreview, + binding.flairCustomTextViewItemPostWithPreview, + binding.awardsTextViewItemPostWithPreview, + binding.bottomConstraintLayoutItemPostWithPreview, + binding.upvoteButtonItemPostWithPreview, + binding.scoreTextViewItemPostWithPreview, + binding.downvoteTextViewItemPostWithPreview, + binding.downvoteButtonItemPostWithPreview, + binding.commentsCountButtonItemPostWithPreview, + binding.saveButtonItemPostWithPreview, + binding.shareButtonItemPostWithPreview); if (mActivity.typeface != null) { - linkTextView.setTypeface(mActivity.typeface); - errorTextView.setTypeface(mActivity.typeface); + binding.linkTextViewItemPostWithPreview.setTypeface(mActivity.typeface); + binding.loadImageErrorTextViewItemPostWithPreview.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); + binding.linkTextViewItemPostWithPreview.setTextColor(mSecondaryTextColor); + binding.imageViewNoPreviewGalleryItemPostWithPreview.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + binding.imageViewNoPreviewGalleryItemPostWithPreview.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + binding.progressBarItemPostWithPreview.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + binding.videoOrGifIndicatorImageViewItemPostWithPreview.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN); + binding.videoOrGifIndicatorImageViewItemPostWithPreview.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); + binding.loadImageErrorTextViewItemPostWithPreview.setTextColor(mPrimaryTextColor); - imageView.setOnClickListener(view -> { + binding.imageViewItemPostWithPreview.setOnClickListener(view -> { int position = getBindingAdapterPosition(); if (position < 0) { return; @@ -3441,28 +3985,28 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { - progressBar.setVisibility(View.VISIBLE); - errorTextView.setVisibility(View.GONE); + binding.loadImageErrorTextViewItemPostWithPreview.setOnClickListener(view -> { + binding.progressBarItemPostWithPreview.setVisibility(View.VISIBLE); + binding.loadImageErrorTextViewItemPostWithPreview.setVisibility(View.GONE); loadImage(this); }); - noPreviewLinkImageView.setOnClickListener(view -> { - imageView.performClick(); + binding.imageViewNoPreviewGalleryItemPostWithPreview.setOnClickListener(view -> { + binding.imageViewItemPostWithPreview.performClick(); }); glideRequestListener = new RequestListener<>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorTextView.setVisibility(View.VISIBLE); + binding.progressBarItemPostWithPreview.setVisibility(View.GONE); + binding.loadImageErrorTextViewItemPostWithPreview.setVisibility(View.VISIBLE); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - errorTextView.setVisibility(View.GONE); - progressBar.setVisibility(View.GONE); + binding.loadImageErrorTextViewItemPostWithPreview.setVisibility(View.GONE); + binding.progressBarItemPostWithPreview.setVisibility(View.GONE); return false; } }; @@ -3500,13 +4044,13 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter requestListener; Post post; @@ -3832,21 +4323,37 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { - 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 (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + if (mMarkPostsAsReadAfterVoting) { markPostRead(post, true); } @@ -4096,27 +4602,31 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { - 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 (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + if (mMarkPostsAsReadAfterVoting) { markPostRead(post, true); } @@ -4192,31 +4707,35 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter itemView.performClick()); + saveButton.setOnClickListener(view -> { if (mAccessToken == null) { Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); @@ -4302,14 +4827,14 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter fetchGfycatOrStreamableVideoCall; private boolean isManuallyPaused; - PostCard2VideoAutoplayViewHolder(View itemView) { + PostCard2BaseVideoAutoplayViewHolder(View itemView, + AspectRatioGifImageView iconGifImageView, + TextView subredditTextView, + TextView communityInstanceTextView, + TextView userTextView, + TextView userInstanceTextView, + ImageView stickiedPostImageView, + TextView postTimeTextView, + TextView titleTextView, + CustomTextView typeTextView, + ImageView crosspostImageView, + ImageView archivedImageView, + ImageView lockedImageView, + CustomTextView nsfwTextView, + CustomTextView spoilerTextView, + CustomTextView flairTextView, + CustomTextView awardsTextView, + AspectRatioFrameLayout aspectRatioFrameLayout, + GifImageView previewImageView, + ImageView errorLoadingGfycatImageView, + PlayerView videoPlayer, + ImageView muteButton, + ImageView fullscreenButton, + ImageView pauseButton, + ImageView playButton, + DefaultTimeBar progressBar, + ConstraintLayout bottomConstraintLayout, + MaterialButton upvoteButton, + TextView scoreTextView, + TextView downvoteTextView, + MaterialButton downvoteButton, + MaterialButton commentsCountButton, + MaterialButton saveButton, + MaterialButton shareButton, + View divider) { super(itemView); - ButterKnife.bind(this, itemView); setBaseView( iconGifImageView, subredditTextView, @@ -4987,11 +5399,22 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { if (helper != null) { if (helper.getVolume() != 0) { - muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_24dp)); helper.setVolume(0f); volume = 0f; mFragment.videoAutoplayChangeMutingOption(true); } else { - muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_24dp)); helper.setVolume(1f); volume = 1f; mFragment.videoAutoplayChangeMutingOption(false); @@ -5047,7 +5470,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter requestListener; - PostCard2WithPreviewViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); + PostCard2WithPreviewViewHolder(@NonNull ItemPostCard2WithPreviewBinding binding) { + super(binding.getRoot()); + this.binding = binding; setBaseView( - iconGifImageView, - subredditTextView, - communityInstanceTextView, - userTextView, - userInstanceTextView, - stickiedPostImageView, - postTimeTextView, - titleTextView, - typeTextView, - archivedImageView, - lockedImageView, - crosspostImageView, - nsfwTextView, - spoilerTextView, - flairTextView, - awardsTextView, - bottomConstraintLayout, - upvoteButton, - scoreTextView, - downvoteTextView, - downvoteButton, - commentsCountTextView, - saveButton, - shareButton, + binding.iconGifImageViewItemPostCard2WithPreview, + binding.subredditNameTextViewItemPostCard2WithPreview, + binding.communityInstanceTextViewItemPostCard2WithPreview, + binding.userTextViewItemPostCard2WithPreview, + binding.userInstanceTextViewItemPostCard2WithPreview, + binding.stickiedPostImageViewItemPostCard2WithPreview, + binding.postTimeTextViewItemPostCard2WithPreview, + binding.titleTextViewItemPostCard2WithPreview, + binding.typeTextViewItemPostCard2WithPreview, + binding.archivedImageViewItemPostCard2WithPreview, + binding.lockedImageViewItemPostCard2WithPreview, + binding.crosspostImageViewItemPostCard2WithPreview, + binding.nsfwTextViewItemPostCard2WithPreview, + binding.spoilerCustomTextViewItemPostCard2WithPreview, + binding.flairCustomTextViewItemPostCard2WithPreview, + binding.awardsTextViewItemPostCard2WithPreview, + binding.bottomConstraintLayoutItemPostCard2WithPreview, + binding.upvoteButtonItemPostCard2WithPreview, + binding.scoreTextViewItemPostCard2WithPreview, + binding.downvoteTextViewItemPostCard2WithPreview, + binding.downvoteButtonItemPostCard2WithPreview, + binding.commentsCountButtonItemPostCard2WithPreview, + binding.saveButtonItemPostCard2WithPreview, + binding.shareButtonItemPostCard2WithPreview, true); if (mActivity.typeface != null) { - linkTextView.setTypeface(mActivity.typeface); - errorTextView.setTypeface(mActivity.typeface); + binding.linkTextViewItemPostCard2WithPreview.setTypeface(mActivity.typeface); + binding.loadImageErrorTextViewItemPostCard2WithPreview.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); + binding.linkTextViewItemPostCard2WithPreview.setTextColor(mSecondaryTextColor); + binding.imageViewNoPreviewGalleryItemPostCard2WithPreview.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + binding.imageViewNoPreviewGalleryItemPostCard2WithPreview.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + binding.progressBarItemPostCard2WithPreview.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + binding.videoOrGifIndicatorImageViewItemPostCard2WithPreview.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN); + binding.videoOrGifIndicatorImageViewItemPostCard2WithPreview.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); + binding.loadImageErrorTextViewItemPostCard2WithPreview.setTextColor(mPrimaryTextColor); + binding.dividerItemPostCard2WithPreview.setBackgroundColor(mDividerColor); - imageView.setOnClickListener(view -> { + binding.imageViewItemPostCard2WithPreview.setOnClickListener(view -> { int position = getBindingAdapterPosition(); if (position < 0) { return; @@ -5335,28 +5775,28 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { - progressBar.setVisibility(View.VISIBLE); - errorTextView.setVisibility(View.GONE); + binding.loadImageErrorTextViewItemPostCard2WithPreview.setOnClickListener(view -> { + binding.progressBarItemPostCard2WithPreview.setVisibility(View.VISIBLE); + binding.loadImageErrorTextViewItemPostCard2WithPreview.setVisibility(View.GONE); loadImage(this); }); - noPreviewImageView.setOnClickListener(view -> { - imageView.performClick(); + binding.imageViewNoPreviewGalleryItemPostCard2WithPreview.setOnClickListener(view -> { + binding.imageViewItemPostCard2WithPreview.performClick(); }); requestListener = new RequestListener<>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorTextView.setVisibility(View.VISIBLE); + binding.progressBarItemPostCard2WithPreview.setVisibility(View.GONE); + binding.loadImageErrorTextViewItemPostCard2WithPreview.setVisibility(View.VISIBLE); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - errorTextView.setVisibility(View.GONE); - progressBar.setVisibility(View.GONE); + binding.loadImageErrorTextViewItemPostCard2WithPreview.setVisibility(View.GONE); + binding.progressBarItemPostCard2WithPreview.setVisibility(View.GONE); return false; } }; @@ -5392,7 +5832,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { + int position = getBindingAdapterPosition(); + if (position >= 0 && canStartActivity) { + Post post = getItem(position); + if (post != null) { + markPostRead(post, true); + + openViewPostDetailActivity(post, getBindingAdapterPosition()); + } + } + }); + + itemView.setOnTouchListener((v, event) -> { + if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { + if (mFragment.isRecyclerViewItemSwipeable(PostMaterial3CardBaseViewHolder.this)) { + mActivity.unlockSwipeRightToGoBack(); + } + } else { + if (mFragment.isRecyclerViewItemSwipeable(PostMaterial3CardBaseViewHolder.this)) { + mActivity.lockSwipeRightToGoBack(); + } + } + return false; + }); + + userTextView.setOnClickListener(view -> { + if (!canStartActivity) { + return; + } + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post == null || post.isAuthorDeleted()) { + return; + } + 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()); + } + + 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 (mMarkPostsAsReadAfterVoting) { + markPostRead(post, true); + } + + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + int previousUpvoteButtonTextColor = upvoteButton.getCurrentTextColor(); + int previousDownvoteButtonTextColor = downvoteButton.getCurrentTextColor(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + Drawable previousUpvoteButtonDrawable = upvoteButton.getIcon(); + Drawable previousDownvoteButtonDrawable = downvoteButton.getIcon(); + + int previousVoteType = post.getVoteType(); + int newVoteType; + + downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); + downvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + + if (previousVoteType != 1) { + //Not upvoted before + post.setVoteType(1); + newVoteType = Integer.parseInt(APIUtils.DIR_UPVOTE); + upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp); + upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor)); + scoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + post.setVoteType(0); + newVoteType = Integer.parseInt(APIUtils.DIR_UNVOTE); + upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); + upvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + + VoteThing.votePost(mActivity, retrofit.getRetrofit(), mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType == Integer.parseInt(APIUtils.DIR_UPVOTE)) { + post.setVoteType(1); + if (currentPosition == position) { + upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp); + upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor)); + scoreTextView.setTextColor(mUpvotedColor); + } + } else { + post.setVoteType(0); + if (currentPosition == position) { + upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); + upvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + } + + if (currentPosition == position) { + downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); + downvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + 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.setIcon(previousUpvoteButtonDrawable); + upvoteButton.setIconTint(ColorStateList.valueOf(previousUpvoteButtonTextColor)); + scoreTextView.setTextColor(previousScoreTextViewColor); + downvoteButton.setIcon(previousDownvoteButtonDrawable); + downvoteButton.setIconTint(ColorStateList.valueOf(previousDownvoteButtonTextColor)); + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }, post.getId(), 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 (mMarkPostsAsReadAfterVoting) { + markPostRead(post, true); + } + + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + int previousUpvoteButtonTextColor = upvoteButton.getTextColors().getDefaultColor(); + int previousDownvoteButtonTextColor = downvoteButton.getTextColors().getDefaultColor(); + Drawable previousUpvoteButtonDrawable = upvoteButton.getIcon(); + Drawable previousDownvoteButtonDrawable = downvoteButton.getIcon(); + + int previousVoteType = post.getVoteType(); + int newVoteType; + + upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); + upvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + scoreTextView.setTextColor(mPostIconAndInfoColor); + + if (previousVoteType != -1) { + //Not downvoted before + post.setVoteType(-1); + newVoteType = Integer.parseInt(APIUtils.DIR_DOWNVOTE); + downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp); + downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor)); + scoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + post.setVoteType(0); + newVoteType = Integer.parseInt(APIUtils.DIR_UNVOTE); + downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); + downvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + if (!mHideTheNumberOfVotes) { + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + } + + VoteThing.votePost(mActivity, retrofit.getRetrofit(), mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType == Integer.parseInt(APIUtils.DIR_DOWNVOTE)) { + post.setVoteType(-1); + if (currentPosition == position) { + downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp); + downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor)); + scoreTextView.setTextColor(mDownvotedColor); + } + } else { + post.setVoteType(0); + if (currentPosition == position) { + downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); + downvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + } + + if (currentPosition == position) { + upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); + upvoteButton.setIconTint(ColorStateList.valueOf(mPostIconAndInfoColor)); + scoreTextView.setTextColor(mPostIconAndInfoColor); + 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.setIcon(previousUpvoteButtonDrawable); + upvoteButton.setIconTint(ColorStateList.valueOf(previousUpvoteButtonTextColor)); + scoreTextView.setTextColor(previousUpvoteButtonTextColor); + downvoteButton.setIcon(previousDownvoteButtonDrawable); + downvoteButton.setIconTint(ColorStateList.valueOf(previousDownvoteButtonTextColor)); + } + + EventBus.getDefault().post(new PostUpdateEventToPostDetailFragment(post)); + } + }, post.getId(), newVoteType, getBindingAdapterPosition()); + } + }); + + commentsCountButton.setOnClickListener(view -> itemView.performClick()); + + 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; + } + SavePost savePost = new SavePost(); + if (post.isSaved()) { + saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); + savePost.unsaveThing(retrofit.getRetrofit(), mAccessToken, post.getId(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(false); + if (getBindingAdapterPosition() == position) { + saveButton.setIconResource(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.setIconResource(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.setIconResource(R.drawable.ic_bookmark_grey_24dp); + savePost.saveThing(retrofit.getRetrofit(), mAccessToken, post.getId(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(true); + if (getBindingAdapterPosition() == position) { + saveButton.setIconResource(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.setIconResource(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); + } + }); + + shareButton.setOnLongClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return false; + } + Post post = getItem(position); + if (post != null) { + mActivity.copyLink(post.getPermalink()); + return true; + } + return false; + }); + } + + void markPostRead(Post post, boolean changePostItemColor) { + if (mAccessToken != null && !post.isRead() && mMarkPostsAsRead) { + post.markAsRead(); + if (changePostItemColor) { + itemView.setBackgroundTintList(ColorStateList.valueOf(mReadPostFilledCardViewBackgroundColor)); + titleTextView.setTextColor(mReadPostTitleColor); + if (this instanceof PostMaterial3CardTextTypeViewHolder) { + ((PostMaterial3CardTextTypeViewHolder) this).binding.contentTextViewItemPostCard3TextType.setTextColor(mReadPostContentColor); + } + } + if (mActivity != null && mActivity instanceof MarkPostAsReadInterface) { + ((MarkPostAsReadInterface) mActivity).markPostAsRead(post); + mFragment.markPostAsRead(post); + } + } + } + } + + class PostMaterial3CardBaseVideoAutoplayViewHolder extends PostMaterial3CardBaseViewHolder implements ToroPlayer { + AspectRatioFrameLayout aspectRatioFrameLayout; + GifImageView previewImageView; + ImageView errorLoadingGfycatImageView; + PlayerView videoPlayer; + ImageView muteButton; + ImageView fullscreenButton; + ImageView pauseButton; + ImageView playButton; + DefaultTimeBar progressBar; + @Nullable + Container container; + @Nullable + ExoPlayerViewHelper helper; + private Uri mediaUri; + private float volume; + public Call fetchGfycatOrStreamableVideoCall; + private boolean isManuallyPaused; + + PostMaterial3CardBaseVideoAutoplayViewHolder(View rootView, + AspectRatioGifImageView iconGifImageView, + TextView subredditTextView, + TextView userTextView, + ImageView stickiedPostImageView, + TextView postTimeTextView, + TextView titleTextView, + AspectRatioFrameLayout aspectRatioFrameLayout, + GifImageView previewImageView, + ImageView errorLoadingGfycatImageView, + PlayerView videoPlayer, + ImageView muteButton, + ImageView fullscreenButton, + ImageView pauseButton, + ImageView playButton, + DefaultTimeBar progressBar, + ConstraintLayout bottomConstraintLayout, + MaterialButton upvoteButton, + TextView scoreTextView, + MaterialButton downvoteButton, + MaterialButton commentsCountButton, + MaterialButton saveButton, + MaterialButton shareButton) { + super(rootView); setBaseView( iconGifImageView, subredditTextView, @@ -5469,29 +6441,608 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter { + if (helper != null) { + if (helper.getVolume() != 0) { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_24dp)); + helper.setVolume(0f); + volume = 0f; + mFragment.videoAutoplayChangeMutingOption(true); + } else { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_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) { + markPostRead(post, true); + 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, post); + if (helper != null) { + intent.putExtra(ViewVideoActivity.EXTRA_PROGRESS_SECONDS, helper.getLatestPlaybackInfo().getResumePosition()); + } + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, post.isNSFW()); + mActivity.startActivity(intent); + } + } + }); + + pauseButton.setOnClickListener(view -> { + pause(); + isManuallyPaused = true; + savePlaybackInfo(getPlayerOrder(), getCurrentPlaybackInfo()); + }); + + playButton.setOnClickListener(view -> { + isManuallyPaused = false; + play(); + }); + + progressBar.addListener(new TimeBar.OnScrubListener() { + @Override + public void onScrubStart(TimeBar timeBar, long position) { + + } + + @Override + public void onScrubMove(TimeBar timeBar, long position) { + + } + + @Override + public void onScrubStop(TimeBar timeBar, long position, boolean canceled) { + if (!canceled) { + savePlaybackInfo(getPlayerOrder(), getCurrentPlaybackInfo()); + } + } + }); + + 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; + } + + private void savePlaybackInfo(int order, @Nullable PlaybackInfo playbackInfo) { + if (container != null) container.savePlaybackInfo(order, playbackInfo); + } + + @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 (this.container == null) { + this.container = container; + } + if (helper == null) { + helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); + helper.addEventListener(new Playable.DefaultEventListener() { + @Override + public void onTracksChanged(@NonNull Tracks tracks) { + ImmutableList trackGroups = tracks.getGroups(); + if (!trackGroups.isEmpty()) { + for (int i = 0; i < trackGroups.size(); i++) { + String mimeType = trackGroups.get(i).getTrackFormat(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_24dp)); + } else { + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_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) { + if (!isPlaying() && isManuallyPaused) { + helper.play(); + pause(); + helper.setVolume(volume); + } else { + 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; + } + isManuallyPaused = false; + container = null; + } + + @Override + public boolean wantsToPlay() { + return canPlayVideo && mediaUri != null && ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= mStartAutoplayVisibleAreaOffset; + } + + @Override + public int getPlayerOrder() { + return getBindingAdapterPosition(); + } + } + + class PostMaterial3CardVideoAutoplayViewHolder extends PostMaterial3CardBaseVideoAutoplayViewHolder { + PostMaterial3CardVideoAutoplayViewHolder(ItemPostCard3VideoTypeAutoplayBinding binding) { + super(binding.getRoot(), + binding.iconGifImageViewItemPostCard3VideoTypeAutoplay, + binding.subredditNameTextViewItemPostCard3VideoTypeAutoplay, + binding.userTextViewItemPostCard3VideoTypeAutoplay, + binding.stickiedPostImageViewItemPostCard3VideoTypeAutoplay, + binding.postTimeTextViewItemPostCard3VideoTypeAutoplay, + binding.titleTextViewItemPostCard3VideoTypeAutoplay, + binding.aspectRatioFrameLayoutItemPostCard3VideoTypeAutoplay, + binding.previewImageViewItemPostCard3VideoTypeAutoplay, + binding.errorLoadingGfycatImageViewItemPostCard3VideoTypeAutoplay, + binding.playerViewItemPostCard3VideoTypeAutoplay, + binding.getRoot().findViewById(R.id.mute_exo_playback_control_view), + binding.getRoot().findViewById(R.id.fullscreen_exo_playback_control_view), + binding.getRoot().findViewById(R.id.exo_pause), + binding.getRoot().findViewById(R.id.exo_play), + binding.getRoot().findViewById(R.id.exo_progress), + binding.bottomConstraintLayoutItemPostCard3VideoTypeAutoplay, + binding.upvoteButtonItemPostCard3VideoTypeAutoplay, + binding.scoreTextViewItemPostCard3VideoTypeAutoplay, + binding.downvoteButtonItemPostCard3VideoTypeAutoplay, + binding.commentsCountButtonItemPostCard3VideoTypeAutoplay, + binding.saveButtonItemPostCard3VideoTypeAutoplay, + binding.shareButtonItemPostCard3VideoTypeAutoplay); + } + } + + class PostMaterial3CardVideoAutoplayLegacyControllerViewHolder extends PostMaterial3CardBaseVideoAutoplayViewHolder { + PostMaterial3CardVideoAutoplayLegacyControllerViewHolder(ItemPostCard3VideoTypeAutoplayLegacyControllerBinding binding) { + super(binding.getRoot(), + binding.iconGifImageViewItemPostCard3VideoTypeAutoplay, + binding.subredditNameTextViewItemPostCard3VideoTypeAutoplay, + binding.userTextViewItemPostCard3VideoTypeAutoplay, + binding.stickiedPostImageViewItemPostCard3VideoTypeAutoplay, + binding.postTimeTextViewItemPostCard3VideoTypeAutoplay, + binding.titleTextViewItemPostCard3VideoTypeAutoplay, + binding.aspectRatioFrameLayoutItemPostCard3VideoTypeAutoplay, + binding.previewImageViewItemPostCard3VideoTypeAutoplay, + binding.errorLoadingGfycatImageViewItemPostCard3VideoTypeAutoplay, + binding.playerViewItemPostCard3VideoTypeAutoplay, + binding.getRoot().findViewById(R.id.mute_exo_playback_control_view), + binding.getRoot().findViewById(R.id.fullscreen_exo_playback_control_view), + binding.getRoot().findViewById(R.id.exo_pause), + binding.getRoot().findViewById(R.id.exo_play), + binding.getRoot().findViewById(R.id.exo_progress), + binding.bottomConstraintLayoutItemPostCard3VideoTypeAutoplay, + binding.upvoteButtonItemPostCard3VideoTypeAutoplay, + binding.scoreTextViewItemPostCard3VideoTypeAutoplay, + binding.downvoteButtonItemPostCard3VideoTypeAutoplay, + binding.commentsCountButtonItemPostCard3VideoTypeAutoplay, + binding.saveButtonItemPostCard3VideoTypeAutoplay, + binding.shareButtonItemPostCard3VideoTypeAutoplay); + } + } + + public class PostMaterial3CardWithPreviewViewHolder extends PostMaterial3CardBaseViewHolder { + + ItemPostCard3WithPreviewBinding binding; + RequestListener glideRequestListener; + + PostMaterial3CardWithPreviewViewHolder(@NonNull ItemPostCard3WithPreviewBinding binding) { + super(binding.getRoot()); + this.binding = binding; + setBaseView(binding.iconGifImageViewItemPostCard3WithPreview, + binding.subredditNameTextViewItemPostCard3WithPreview, + binding.communityInstanceTextViewItemPostCard3WithPreview, + binding.userTextViewItemPostCard3WithPreview, + binding.userInstanceTextViewItemPostCard3WithPreview, + binding.stickiedPostImageViewItemPostCard3WithPreview, + binding.postTimeTextViewItemPostCard3WithPreview, + binding.titleTextViewItemPostCard3WithPreview, + binding.bottomConstraintLayoutItemPostCard3WithPreview, + binding.upvoteButtonItemPostCard3WithPreview, + binding.scoreTextViewItemPostCard3WithPreview, + binding.downvoteTextViewItemPostCard3WithPreview, + binding.downvoteButtonItemPostCard3WithPreview, + binding.commentsCountButtonItemPostCard3WithPreview, + binding.saveButtonItemPostCard3WithPreview, + binding.shareButtonItemPostCard3WithPreview); + + if (mActivity.typeface != null) { + binding.linkTextViewItemPostCard3WithPreview.setTypeface(mActivity.typeface); + binding.loadImageErrorTextViewItemPostCard3WithPreview.setTypeface(mActivity.typeface); + } + binding.linkTextViewItemPostCard3WithPreview.setTextColor(mSecondaryTextColor); + binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + binding.progressBarItemPostCard3WithPreview.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN); + binding.videoOrGifIndicatorImageViewItemPostCard3WithPreview.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); + binding.loadImageErrorTextViewItemPostCard3WithPreview.setTextColor(mPrimaryTextColor); + + binding.imageViewItemPostCard3WithPreview.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + markPostRead(post, true); + openMedia(post); + } + }); + + binding.loadImageErrorTextViewItemPostCard3WithPreview.setOnClickListener(view -> { + binding.progressBarItemPostCard3WithPreview.setVisibility(View.VISIBLE); + binding.loadImageErrorTextViewItemPostCard3WithPreview.setVisibility(View.GONE); + loadImage(this); + }); + + binding.imageViewNoPreviewGalleryItemPostCard3WithPreview.setOnClickListener(view -> { + binding.imageViewItemPostCard3WithPreview.performClick(); + }); + + glideRequestListener = new RequestListener<>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + binding.progressBarItemPostCard3WithPreview.setVisibility(View.GONE); + binding.loadImageErrorTextViewItemPostCard3WithPreview.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + binding.loadImageErrorTextViewItemPostCard3WithPreview.setVisibility(View.GONE); + binding.progressBarItemPostCard3WithPreview.setVisibility(View.GONE); + return false; + } + }; + } + } + + public class PostMaterial3CardBaseGalleryTypeViewHolder extends PostMaterial3CardBaseViewHolder { + FrameLayout frameLayout; + RecyclerView galleryRecyclerView; + CustomTextView imageIndexTextView; + ImageView noPreviewImageView; + + PostGalleryTypeImageRecyclerViewAdapter adapter; + private boolean swipeLocked; + + PostMaterial3CardBaseGalleryTypeViewHolder(View rootView, + AspectRatioGifImageView iconGifImageView, + TextView subredditTextView, + TextView communityInstanceTextView, + TextView userTextView, + TextView userInstanceTextView, + ImageView stickiedPostImageView, + TextView postTimeTextView, + TextView titleTextView, + FrameLayout frameLayout, + RecyclerView galleryRecyclerView, + CustomTextView imageIndexTextView, + ImageView noPreviewImageView, + ConstraintLayout bottomConstraintLayout, + MaterialButton upvoteButton, + TextView scoreTextView, + TextView downvoteTextView, + MaterialButton downvoteButton, + MaterialButton commentsCountButton, + MaterialButton saveButton, + MaterialButton shareButton) { + super(rootView); + setBaseView( + iconGifImageView, + subredditTextView, + communityInstanceTextView, + userTextView, + userInstanceTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteTextView, + downvoteButton, + commentsCountButton, + saveButton, + shareButton); + + this.frameLayout = frameLayout; + this.galleryRecyclerView = galleryRecyclerView; + this.imageIndexTextView = imageIndexTextView; + this.noPreviewImageView = noPreviewImageView; + + imageIndexTextView.setTextColor(mMediaIndicatorIconTint); + imageIndexTextView.setBackgroundColor(mMediaIndicatorBackgroundColor); + imageIndexTextView.setBorderColor(mMediaIndicatorBackgroundColor); + if (mActivity.typeface != null) { + imageIndexTextView.setTypeface(mActivity.typeface); + } + + noPreviewImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + noPreviewImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + + adapter = new PostGalleryTypeImageRecyclerViewAdapter(mGlide, mActivity.typeface, + mSaveMemoryCenterInsideDownsampleStrategy, mColorAccent, mPrimaryTextColor, mScale); + galleryRecyclerView.setAdapter(adapter); + galleryRecyclerView.setOnTouchListener((v, motionEvent) -> { + if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP || motionEvent.getActionMasked() == MotionEvent.ACTION_CANCEL) { + if (mActivity.mSliderPanel != null) { + mActivity.mSliderPanel.requestDisallowInterceptTouchEvent(false); + } + + if (mActivity.mViewPager2 != null) { + mActivity.mViewPager2.setUserInputEnabled(true); + } + mActivity.unlockSwipeRightToGoBack(); + swipeLocked = false; + } else { + if (mActivity.mSliderPanel != null) { + mActivity.mSliderPanel.requestDisallowInterceptTouchEvent(true); + } + if (mActivity.mViewPager2 != null) { + mActivity.mViewPager2.setUserInputEnabled(false); + } + mActivity.lockSwipeRightToGoBack(); + swipeLocked = true; + } + + return false; + }); + new PagerSnapHelper().attachToRecyclerView(galleryRecyclerView); + galleryRecyclerView.setRecycledViewPool(mGalleryRecycledViewPool); + LinearLayoutManagerBugFixed layoutManager = new LinearLayoutManagerBugFixed(mActivity, RecyclerView.HORIZONTAL, false); + galleryRecyclerView.setLayoutManager(layoutManager); + galleryRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + } + + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, layoutManager.findFirstVisibleItemPosition() + 1, post.getGallery().size())); + } + }); + galleryRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { + private float downX; + private float downY; + private boolean dragged; + private final int minTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop(); + + @Override + public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + int action = e.getAction(); + switch (action) { + case MotionEvent.ACTION_DOWN: + downX = e.getRawX(); + downY = e.getRawY(); + break; + case MotionEvent.ACTION_MOVE: + if (Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) { + dragged = true; + } + break; + case MotionEvent.ACTION_UP: + if (!dragged) { + int position = getBindingAdapterPosition(); + if (position >= 0) { + if (post != null) { + markPostRead(post, true); + openMedia(post, layoutManager.findFirstVisibleItemPosition()); + } + } + } + + downX = 0; + downY = 0; + dragged = false; + } + return false; + } + + @Override + public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + + } + + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + + } + }); + + noPreviewImageView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position < 0) { + return; + } + if (post != null) { + markPostRead(post, true); + openMedia(post, 0); + } + }); + } + + public boolean isSwipeLocked() { + return swipeLocked; + } + } + + public class PostMaterial3CardGalleryTypeViewHolder extends PostMaterial3CardBaseGalleryTypeViewHolder { + + PostMaterial3CardGalleryTypeViewHolder(ItemPostCard3GalleryTypeBinding binding) { + super(binding.getRoot(), + binding.iconGifImageViewItemPostCard3GalleryType, + binding.subredditNameTextViewItemPostCard3GalleryType, + binding.communityInstanceTextViewItemPostCard3GalleryType, + binding.userTextViewItemPostCard3GalleryType, + binding.userInstanceTextViewItemPostCard3GalleryType, + binding.stickiedPostImageViewItemPostCard3GalleryType, + binding.postTimeTextViewItemPostCard3GalleryType, + binding.titleTextViewItemPostCard3GalleryType, + binding.galleryFrameLayoutItemPostCard3GalleryType, + binding.galleryRecyclerViewItemPostCard3GalleryType, + binding.imageIndexTextViewItemPostCard3GalleryType, + binding.noPreviewImageViewItemPostCard3GalleryType, + binding.bottomConstraintLayoutItemPostCard3GalleryType, + binding.upvoteButtonItemPostCard3GalleryType, + binding.scoreTextViewItemPostCard3GalleryType, + binding.downvoteTextViewItemPostCard3GalleryType, + binding.downvoteButtonItemPostCard3GalleryType, + binding.commentsCountButtonItemPostCard3GalleryType, + binding.saveButtonItemPostCard3GalleryType, + binding.shareButtonItemPostCard3GalleryType); + } + } + + class PostMaterial3CardTextTypeViewHolder extends PostMaterial3CardBaseViewHolder { + + ItemPostCard3TextBinding binding; + + PostMaterial3CardTextTypeViewHolder(@NonNull ItemPostCard3TextBinding binding) { + super(binding.getRoot()); + this.binding = binding; + setBaseView( + binding.iconGifImageViewItemPostCard3TextType, + binding.subredditNameTextViewItemPostCard3TextType, + binding.communityInstanceTextViewItemPostCard3TextType, + binding.userTextViewItemPostCard3TextType, + binding.userInstanceTextViewItemPostCard3TextType, + binding.stickiedPostImageViewItemPostCard3TextType, + binding.postTimeTextViewItemPostCard3TextType, + binding.titleTextViewItemPostCard3TextType, + binding.bottomConstraintLayoutItemPostCard3TextType, + binding.upvoteButtonItemPostCard3TextType, + binding.scoreTextViewItemPostCard3TextType, + binding.downvoteTextViewItemPostCard3TextType, + binding.downvoteButtonItemPostCard3TextType, + binding.commentsCountButtonItemPostCard3TextType, + binding.saveButtonItemPostCard3TextType, + binding.shareButtonItemPostCard3TextType); if (mActivity.contentTypeface != null) { - contentTextView.setTypeface(mActivity.contentTypeface); + binding.contentTextViewItemPostCard3TextType.setTypeface(mActivity.titleTypeface); } - contentTextView.setTextColor(mPostContentColor); - divider.setBackgroundColor(mDividerColor); + binding.contentTextViewItemPostCard3TextType.setTextColor(mPostContentColor); } } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/SearchActivityRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/SearchActivityRecyclerViewAdapter.java index ef25738f..11e964d9 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/SearchActivityRecyclerViewAdapter.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/SearchActivityRecyclerViewAdapter.java @@ -2,21 +2,17 @@ package eu.toldi.infinityforlemmy.adapters; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.List; -import butterknife.BindView; -import butterknife.ButterKnife; import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.activities.BaseActivity; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; +import eu.toldi.infinityforlemmy.databinding.ItemRecentSearchQueryBinding; import eu.toldi.infinityforlemmy.recentsearchquery.RecentSearchQuery; import eu.toldi.infinityforlemmy.utils.Utils; @@ -45,14 +41,14 @@ public class SearchActivityRecyclerViewAdapter extends RecyclerView.Adapter { @@ -92,7 +84,7 @@ public class SearchActivityRecyclerViewAdapter extends RecyclerView.Adapter { + binding.deleteButtonItemRecentSearchQuery.setOnClickListener(view -> { itemOnClickListener.onDelete(recentSearchQueries.get(getBindingAdapterPosition())); }); } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/navigationdrawer/PostFilterUsageEmbeddedRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/navigationdrawer/PostFilterUsageEmbeddedRecyclerViewAdapter.java new file mode 100644 index 00000000..e239e4d4 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/navigationdrawer/PostFilterUsageEmbeddedRecyclerViewAdapter.java @@ -0,0 +1,102 @@ +package eu.toldi.infinityforlemmy.adapters.navigationdrawer; + +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import eu.toldi.infinityforlemmy.R; +import eu.toldi.infinityforlemmy.activities.BaseActivity; +import eu.toldi.infinityforlemmy.databinding.ItemPostFilterUsageEmbeddedBinding; +import eu.toldi.infinityforlemmy.postfilter.PostFilterUsage; + + +public class PostFilterUsageEmbeddedRecyclerViewAdapter extends RecyclerView.Adapter { + + private BaseActivity baseActivity; + private List postFilterUsageList; + + public PostFilterUsageEmbeddedRecyclerViewAdapter(BaseActivity baseActivity) { + this.baseActivity = baseActivity; + } + + @NonNull + @Override + public EntryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new EntryViewHolder(ItemPostFilterUsageEmbeddedBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull EntryViewHolder holder, int position) { + if (postFilterUsageList == null || postFilterUsageList.isEmpty()) { + holder.textView.setText(R.string.click_to_apply_post_filter); + } else if (holder.getBindingAdapterPosition() > 4) { + holder.textView.setText(baseActivity.getString(R.string.post_filter_usage_embedded_more_count, postFilterUsageList.size() - 5)); + } else { + PostFilterUsage postFilterUsage = postFilterUsageList.get(holder.getBindingAdapterPosition()); + switch (postFilterUsage.usage) { + case PostFilterUsage.HOME_TYPE: + holder.textView.setText(R.string.post_filter_usage_home); + break; + case PostFilterUsage.SUBREDDIT_TYPE: + if (postFilterUsage.nameOfUsage.equals(PostFilterUsage.NO_USAGE)) { + holder.textView.setText(R.string.post_filter_usage_embedded_subreddit_all); + } else { + holder.textView.setText("r/" + postFilterUsage.nameOfUsage); + } + break; + case PostFilterUsage.USER_TYPE: + if (postFilterUsage.nameOfUsage.equals(PostFilterUsage.NO_USAGE)) { + holder.textView.setText(R.string.post_filter_usage_embedded_user_all); + } else { + holder.textView.setText("u/" + postFilterUsage.nameOfUsage); + } + break; + case PostFilterUsage.SEARCH_TYPE: + holder.textView.setText(R.string.post_filter_usage_search); + break; + case PostFilterUsage.MULTIREDDIT_TYPE: + if (postFilterUsage.nameOfUsage.equals(PostFilterUsage.NO_USAGE)) { + holder.textView.setText(R.string.post_filter_usage_embedded_multireddit_all); + } else { + holder.textView.setText(postFilterUsage.nameOfUsage); + } + break; + } + } + } + + @Override + public int getItemCount() { + return postFilterUsageList == null || postFilterUsageList.isEmpty() ? 1 : (postFilterUsageList.size() > 5 ? 6 : postFilterUsageList.size()); + } + + public void setPostFilterUsageList(List postFilterUsageList) { + this.postFilterUsageList = postFilterUsageList; + notifyDataSetChanged(); + } + + class EntryViewHolder extends RecyclerView.ViewHolder { + TextView textView; + + public EntryViewHolder(@NonNull ItemPostFilterUsageEmbeddedBinding binding) { + super(binding.getRoot()); + textView = binding.getRoot(); + + textView.setTextColor(baseActivity.customThemeWrapper.getSecondaryTextColor()); + + if (baseActivity.typeface != null) { + textView.setTypeface(baseActivity.typeface); + } + + textView.setOnClickListener(view -> { + Toast.makeText(baseActivity, textView.getText(), Toast.LENGTH_SHORT).show(); + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedditAPI.java b/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedditAPI.java index 7fb73455..dac38089 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedditAPI.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedditAPI.java @@ -54,19 +54,19 @@ public interface RedditAPI { @GET("user/{username}/about.json?raw_json=1") Call getUserData(@Path("username") String username); - @GET("user/{username}/about.json?raw_json=1") + @GET("user/{username}/about.json?raw_json=1&limit=100") Call getUserDataOauth(@HeaderMap Map headers, @Path("username") String username); - @GET("user/{username}/comments.json?raw_json=1") + @GET("user/{username}/comments.json?raw_json=1&limit=100") Call getUserComments(@Path("username") String username, @Query("after") String after, @Query("sort") SortType.Type sortType, @Query("t") SortType.Time sortTime); - @GET("user/{username}/comments.json?raw_json=1") + @GET("user/{username}/comments.json?raw_json=1&limit=100") Call getUserCommentsOauth(@HeaderMap Map headers, @Path("username") String username, @Query("after") String after, @Query("sort") SortType.Type sortType, @Query("t") SortType.Time sortTime); - @GET("user/{username}/{where}.json?&type=comments&raw_json=1&limit=25") + @GET("user/{username}/{where}.json?&type=comments&raw_json=1&limit=100") Call getUserSavedCommentsOauth(@Path("username") String username, @Path("where") String where, @Query("after") String lastItem, @Query("sort") SortType.Type sortType, @Query("t") SortType.Time sortTime, @HeaderMap Map headers); @@ -273,108 +273,108 @@ public interface RedditAPI { @GET("/r/{subredditName}/wiki/{wikiPage}.json?raw_json=1") Call getWikiPage(@Path("subredditName") String subredditName, @Path("wikiPage") String wikiPage); - @GET("{sortType}?raw_json=1") + @GET("{sortType}?raw_json=1&limit=100") ListenableFuture> getBestPostsListenableFuture(@Path("sortType") SortType.Type sortType, @Query("t") SortType.Time sortTime, @Query("after") String lastItem, @HeaderMap Map headers); - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=100&always_show_media=1") ListenableFuture> getSubredditBestPostsOauthListenableFuture(@Path("subredditName") String subredditName, @Path("sortType") SortType.Type sortType, @Query("t") SortType.Time sortTime, @Query("after") String lastItem, @HeaderMap Map headers); - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=100&always_show_media=1") ListenableFuture> getSubredditBestPostsListenableFuture(@Path("subredditName") String subredditName, @Path("sortType") SortType.Type sortType, @Query("t") SortType.Time sortTime, @Query("after") String lastItem); - @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") + @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=100") ListenableFuture> getUserPostsOauthListenableFuture(@Path("username") String username, @Path("where") String where, @Query("after") String lastItem, @Query("sort") SortType.Type sortType, @Query("t") SortType.Time sortTime, @HeaderMap Map headers); - @GET("user/{username}/submitted.json?raw_json=1&limit=25") + @GET("user/{username}/submitted.json?raw_json=1&limit=100") ListenableFuture> getUserPostsListenableFuture(@Path("username") String username, @Query("after") String lastItem, @Query("sort") SortType.Type sortType, @Query("t") SortType.Time sortTime); - @GET("search.json?include_over_18=1&raw_json=1&type=link") + @GET("search.json?include_over_18=1&raw_json=1&limit=100&type=link") ListenableFuture> searchPostsOauthListenableFuture(@Query("q") String query, @Query("after") String after, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("source") String source, @HeaderMap Map headers); - @GET("search.json?include_over_18=1&raw_json=1&type=link") + @GET("search.json?include_over_18=1&raw_json=1&limit=100&type=link") ListenableFuture> searchPostsListenableFuture(@Query("q") String query, @Query("after") String after, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("source") String source); - @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&limit=100&type=link&restrict_sr=true") ListenableFuture> searchPostsInSpecificSubredditOauthListenableFuture(@Path("subredditName") String subredditName, @Query("q") String query, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("after") String after, @HeaderMap Map headers); - @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&limit=100&type=link&restrict_sr=true") ListenableFuture> searchPostsInSpecificSubredditListenableFuture(@Path("subredditName") String subredditName, @Query("q") String query, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("after") String after); - @GET("{multipath}?raw_json=1") + @GET("{multipath}?raw_json=1&limit=100") ListenableFuture> getMultiRedditPostsListenableFuture(@Path(value = "multipath", encoded = true) String multiPath, @Query("after") String after, @Query("t") SortType.Time sortTime); - @GET("{multipath}.json?raw_json=1") + @GET("{multipath}.json?raw_json=1&limit=100") ListenableFuture> getMultiRedditPostsOauthListenableFuture(@Path(value = "multipath", encoded = true) String multiPath, @Query("after") String after, @Query("t") SortType.Time sortTime, @HeaderMap Map headers); - @GET("{sortType}?raw_json=1") + @GET("{sortType}?raw_json=1&limit=100") Call getBestPosts(@Path("sortType") SortType.Type sortType, @Query("t") SortType.Time sortTime, @Query("after") String lastItem, @HeaderMap Map headers); - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=100&always_show_media=1") Call getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") SortType.Type sortType, @Query("t") SortType.Time sortTime, @Query("after") String lastItem, @HeaderMap Map headers); - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=100&always_show_media=1") Call getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") SortType.Type sortType, @Query("t") SortType.Time sortTime, @Query("after") String lastItem); - @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") + @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=100") Call getUserPostsOauth(@Path("username") String username, @Path("where") String where, @Query("after") String lastItem, @Query("sort") SortType.Type sortType, @Query("t") SortType.Time sortTime, @HeaderMap Map headers); - @GET("user/{username}/submitted.json?raw_json=1&limit=25") + @GET("user/{username}/submitted.json?raw_json=1&limit=100") Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, @Query("sort") SortType.Type sortType, @Query("t") SortType.Time sortTime); - @GET("search.json?include_over_18=1&raw_json=1&type=link") + @GET("search.json?include_over_18=1&raw_json=1&limit=100&type=link") Call searchPostsOauth(@Query("q") String query, @Query("after") String after, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("source") String source, @HeaderMap Map headers); - @GET("search.json?include_over_18=1&raw_json=1&type=link") + @GET("search.json?include_over_18=1&raw_json=1&limit=100&type=link") Call searchPosts(@Query("q") String query, @Query("after") String after, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("source") String source); - @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&limit=100&type=link&restrict_sr=true") Call searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, @Query("q") String query, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("after") String after, @HeaderMap Map headers); - @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&limit=100&type=link&restrict_sr=true") Call searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName, @Query("q") String query, @Query("sort") SortType.Type sort, @Query("t") SortType.Time sortTime, @Query("after") String after); - @GET("{multipath}?raw_json=1") + @GET("{multipath}?raw_json=1&limit=100") Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, @Query("after") String after, @Query("t") SortType.Time sortTime); - @GET("{multipath}.json?raw_json=1") + @GET("{multipath}.json?raw_json=1&limit=100") Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, @Query("after") String after, @Query("t") SortType.Time sortTime, @HeaderMap Map headers); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterOptionsBottomSheetFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterOptionsBottomSheetFragment.java new file mode 100644 index 00000000..a85dd8fb --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterOptionsBottomSheetFragment.java @@ -0,0 +1,63 @@ +package eu.toldi.infinityforlemmy.bottomsheetfragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import eu.toldi.infinityforlemmy.activities.CommentFilterPreferenceActivity; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; +import eu.toldi.infinityforlemmy.customviews.LandscapeExpandedRoundedBottomSheetDialogFragment; +import eu.toldi.infinityforlemmy.databinding.FragmentCommentFilterOptionsBottomSheetBinding; +import eu.toldi.infinityforlemmy.utils.Utils; + + +public class CommentFilterOptionsBottomSheetFragment extends LandscapeExpandedRoundedBottomSheetDialogFragment { + + public static final String EXTRA_POST_FILTER = "EPF"; + private CommentFilterPreferenceActivity activity; + + public CommentFilterOptionsBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + FragmentCommentFilterOptionsBottomSheetBinding binding = FragmentCommentFilterOptionsBottomSheetBinding.inflate(inflater, container, false); + + CommentFilter commentFilter = getArguments().getParcelable(EXTRA_POST_FILTER); + + binding.editTextViewCommentFilterOptionsBottomSheetFragment.setOnClickListener(view -> { + activity.editCommentFilter(commentFilter); + dismiss(); + }); + + binding.applyToTextViewCommentFilterOptionsBottomSheetFragment.setOnClickListener(view -> { + activity.applyCommentFilterTo(commentFilter); + dismiss(); + }); + + binding.deleteTextViewCommentFilterOptionsBottomSheetFragment.setOnClickListener(view -> { + activity.deleteCommentFilter(commentFilter); + dismiss(); + }); + + if (activity.typeface != null) { + Utils.setFontToAllTextViews(binding.getRoot(), activity.typeface); + } + + return binding.getRoot(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (CommentFilterPreferenceActivity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterUsageOptionsBottomSheetFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterUsageOptionsBottomSheetFragment.java new file mode 100644 index 00000000..80fd20c9 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/CommentFilterUsageOptionsBottomSheetFragment.java @@ -0,0 +1,57 @@ +package eu.toldi.infinityforlemmy.bottomsheetfragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import eu.toldi.infinityforlemmy.activities.CommentFilterUsageListingActivity; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; +import eu.toldi.infinityforlemmy.customviews.LandscapeExpandedRoundedBottomSheetDialogFragment; +import eu.toldi.infinityforlemmy.databinding.FragmentCommentFilterUsageOptionsBottomSheetBinding; +import eu.toldi.infinityforlemmy.utils.Utils; + +public class CommentFilterUsageOptionsBottomSheetFragment extends LandscapeExpandedRoundedBottomSheetDialogFragment { + + public static final String EXTRA_COMMENT_FILTER_USAGE = "ECFU"; + + private CommentFilterUsageListingActivity activity; + + public CommentFilterUsageOptionsBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + FragmentCommentFilterUsageOptionsBottomSheetBinding binding = FragmentCommentFilterUsageOptionsBottomSheetBinding.inflate(inflater, container, false); + + CommentFilterUsage commentFilterUsage = getArguments().getParcelable(EXTRA_COMMENT_FILTER_USAGE); + + binding.editTextViewCommentFilterUsageOptionsBottomSheetFragment.setOnClickListener(view -> { + activity.editCommentFilterUsage(commentFilterUsage); + dismiss(); + }); + + binding.deleteTextViewCommentFilterUsageOptionsBottomSheetFragment.setOnClickListener(view -> { + activity.deleteCommentFilterUsage(commentFilterUsage); + dismiss(); + }); + + if (activity.typeface != null) { + Utils.setFontToAllTextViews(binding.getRoot(), activity.typeface); + } + + return binding.getRoot(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (CommentFilterUsageListingActivity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/NewCommentFilterUsageBottomSheetFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/NewCommentFilterUsageBottomSheetFragment.java new file mode 100644 index 00000000..5165a115 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/NewCommentFilterUsageBottomSheetFragment.java @@ -0,0 +1,48 @@ +package eu.toldi.infinityforlemmy.bottomsheetfragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import eu.toldi.infinityforlemmy.activities.CommentFilterUsageListingActivity; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; +import eu.toldi.infinityforlemmy.customviews.LandscapeExpandedRoundedBottomSheetDialogFragment; +import eu.toldi.infinityforlemmy.databinding.FragmentNewCommentFilterUsageBottomSheetBinding; +import eu.toldi.infinityforlemmy.utils.Utils; + + +public class NewCommentFilterUsageBottomSheetFragment extends LandscapeExpandedRoundedBottomSheetDialogFragment { + private CommentFilterUsageListingActivity activity; + + public NewCommentFilterUsageBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + FragmentNewCommentFilterUsageBottomSheetBinding binding = FragmentNewCommentFilterUsageBottomSheetBinding.inflate(inflater, container, false); + + binding.subredditTextViewNewCommentFilterUsageBottomSheetFragment.setOnClickListener(view -> { + activity.newCommentFilterUsage(CommentFilterUsage.SUBREDDIT_TYPE); + dismiss(); + }); + + if (activity.typeface != null) { + Utils.setFontToAllTextViews(binding.getRoot(), activity.typeface); + } + + return binding.getRoot(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (CommentFilterUsageListingActivity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostFilterOptionsBottomSheetFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostFilterOptionsBottomSheetFragment.java index 01a982a1..49f12f80 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostFilterOptionsBottomSheetFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostFilterOptionsBottomSheetFragment.java @@ -5,26 +5,17 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.TextView; import androidx.annotation.NonNull; -import butterknife.BindView; -import butterknife.ButterKnife; -import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.activities.PostFilterPreferenceActivity; import eu.toldi.infinityforlemmy.customviews.LandscapeExpandedRoundedBottomSheetDialogFragment; +import eu.toldi.infinityforlemmy.databinding.FragmentPostFilterOptionsBottomSheetBinding; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.utils.Utils; public class PostFilterOptionsBottomSheetFragment extends LandscapeExpandedRoundedBottomSheetDialogFragment { - @BindView(R.id.edit_text_view_post_filter_options_bottom_sheet_fragment) - TextView editTextView; - @BindView(R.id.apply_to_text_view_post_filter_options_bottom_sheet_fragment) - TextView applyToTextView; - @BindView(R.id.delete_text_view_post_filter_options_bottom_sheet_fragment) - TextView deleteTextView; public static final String EXTRA_POST_FILTER = "EPF"; private PostFilterPreferenceActivity activity; @@ -36,32 +27,30 @@ public class PostFilterOptionsBottomSheetFragment extends LandscapeExpandedRound public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_post_filter_options_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); + FragmentPostFilterOptionsBottomSheetBinding binding = FragmentPostFilterOptionsBottomSheetBinding.inflate(inflater, container, false); PostFilter postFilter = getArguments().getParcelable(EXTRA_POST_FILTER); - editTextView.setOnClickListener(view -> { + binding.editTextViewPostFilterOptionsBottomSheetFragment.setOnClickListener(view -> { activity.editPostFilter(postFilter); dismiss(); }); - applyToTextView.setOnClickListener(view -> { + binding.applyToTextViewPostFilterOptionsBottomSheetFragment.setOnClickListener(view -> { activity.applyPostFilterTo(postFilter); dismiss(); }); - deleteTextView.setOnClickListener(view -> { + binding.deleteTextViewPostFilterOptionsBottomSheetFragment.setOnClickListener(view -> { activity.deletePostFilter(postFilter); dismiss(); }); if (activity.typeface != null) { - Utils.setFontToAllTextViews(rootView, activity.typeface); + Utils.setFontToAllTextViews(binding.getRoot(), activity.typeface); } - return rootView; + return binding.getRoot(); } @Override diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostLayoutBottomSheetFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostLayoutBottomSheetFragment.java index 216630ee..a76343db 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostLayoutBottomSheetFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/PostLayoutBottomSheetFragment.java @@ -6,16 +6,13 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import butterknife.BindView; -import butterknife.ButterKnife; -import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.activities.BaseActivity; import eu.toldi.infinityforlemmy.customviews.LandscapeExpandedRoundedBottomSheetDialogFragment; +import eu.toldi.infinityforlemmy.databinding.FragmentPostLayoutBottomSheetBinding; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.Utils; @@ -24,14 +21,7 @@ import eu.toldi.infinityforlemmy.utils.Utils; */ public class PostLayoutBottomSheetFragment extends LandscapeExpandedRoundedBottomSheetDialogFragment { - @BindView(R.id.card_layout_text_view_post_layout_bottom_sheet_fragment) - TextView cardLayoutTextView; - @BindView(R.id.card_layout_2_text_view_post_layout_bottom_sheet_fragment) - TextView cardLayout2TextView; - @BindView(R.id.compact_layout_text_view_post_layout_bottom_sheet_fragment) - TextView compactLayoutTextView; - @BindView(R.id.gallery_layout_text_view_post_layout_bottom_sheet_fragment) - TextView galleryLayoutTextView; + private FragmentPostLayoutBottomSheetBinding binding; private BaseActivity activity; public PostLayoutBottomSheetFragment() { // Required empty public constructor @@ -39,33 +29,36 @@ public class PostLayoutBottomSheetFragment extends LandscapeExpandedRoundedBotto @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_post_layot_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); + binding = FragmentPostLayoutBottomSheetBinding.inflate(inflater, container, false); - cardLayoutTextView.setOnClickListener(view -> { + binding.cardLayoutTextViewPostLayoutBottomSheetFragment.setOnClickListener(view -> { ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_CARD); dismiss(); }); - compactLayoutTextView.setOnClickListener(view -> { + binding.compactLayoutTextViewPostLayoutBottomSheetFragment.setOnClickListener(view -> { ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_COMPACT); dismiss(); }); - galleryLayoutTextView.setOnClickListener(view -> { + binding.galleryLayoutTextViewPostLayoutBottomSheetFragment.setOnClickListener(view -> { ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_GALLERY); dismiss(); }); - cardLayout2TextView.setOnClickListener(view -> { + binding.cardLayout2TextViewPostLayoutBottomSheetFragment.setOnClickListener(view -> { ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_CARD_2); dismiss(); }); + binding.cardLayout3TextViewPostLayoutBottomSheetFragment.setOnClickListener(view -> { + ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_CARD_3); + dismiss(); + }); if (activity.typeface != null) { - Utils.setFontToAllTextViews(rootView, activity.typeface); + Utils.setFontToAllTextViews(binding.getRoot(), activity.typeface); } - return rootView; + return binding.getRoot(); } @Override diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/RedditAPIInfoBottomSheetFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/RedditAPIInfoBottomSheetFragment.java deleted file mode 100644 index 5537ddb9..00000000 --- a/app/src/main/java/eu/toldi/infinityforlemmy/bottomsheetfragments/RedditAPIInfoBottomSheetFragment.java +++ /dev/null @@ -1,73 +0,0 @@ -package eu.toldi.infinityforlemmy.bottomsheetfragments; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.text.SpannableString; -import android.text.util.Linkify; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; - -import me.saket.bettermovementmethod.BetterLinkMovementMethod; -import eu.toldi.infinityforlemmy.R; -import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; -import eu.toldi.infinityforlemmy.activities.MainActivity; -import eu.toldi.infinityforlemmy.customviews.LandscapeExpandedRoundedBottomSheetDialogFragment; -import eu.toldi.infinityforlemmy.databinding.FragmentRedditApiInfoBottomSheetBinding; -import eu.toldi.infinityforlemmy.utils.Utils; - -public class RedditAPIInfoBottomSheetFragment extends LandscapeExpandedRoundedBottomSheetDialogFragment { - - private MainActivity mainActivity; - - public RedditAPIInfoBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - FragmentRedditApiInfoBottomSheetBinding binding = FragmentRedditApiInfoBottomSheetBinding.inflate(inflater, container, false); - - if (mainActivity != null && mainActivity.typeface != null) { - Utils.setFontToAllTextViews(binding.getRoot(), mainActivity.typeface); - } - - binding.getRoot().setNestedScrollingEnabled(true); - - SpannableString message = new SpannableString(getString(R.string.reddit_api_info, "https://www.reddit.com/r/reddit/comments/145bram/addressing_the_community_about_changes_to_our_api", "https://www.reddit.com/r/Infinity_For_Reddit/comments/147bhsg/the_future_of_infinity")); - Linkify.addLinks(message, Linkify.WEB_URLS); - binding.messageTextViewRedditApiInfoBottomSheetFragment.setText(message); - binding.messageTextViewRedditApiInfoBottomSheetFragment.setMovementMethod(BetterLinkMovementMethod.newInstance().setOnLinkClickListener((textView, url) -> { - Intent intent = new Intent(mainActivity, LinkResolverActivity.class); - intent.setData(Uri.parse(url)); - startActivity(intent); - return true; - })); - binding.messageTextViewRedditApiInfoBottomSheetFragment.setLinkTextColor(getResources().getColor(R.color.colorAccent)); - - binding.doNotShowThisAgainTextView.setOnClickListener(view -> { - binding.doNotShowThisAgainCheckBox.toggle(); - }); - - binding.continueButtonRedditApiInfoBottomSheetFragment.setOnClickListener(view -> { - if (binding.doNotShowThisAgainCheckBox.isChecked()) { - mainActivity.doNotShowRedditAPIInfoAgain(); - } - dismiss(); - }); - - return binding.getRoot(); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mainActivity = (MainActivity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/comment/CommentViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/comment/CommentViewModel.java index fb926683..e36334f6 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/comment/CommentViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/comment/CommentViewModel.java @@ -35,13 +35,14 @@ public class CommentViewModel extends ViewModel { hasCommentLiveData = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(), CommentDataSource::hasPostLiveData); - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); + sortTypeLiveData = new MutableLiveData<>(sortType); PagedList.Config pagedListConfig = (new PagedList.Config.Builder()) .setEnablePlaceholders(false) - .setPageSize(25) + .setPageSize(100) + .setPrefetchDistance(10) + .setInitialLoadSizeHint(10) .build(); comments = Transformations.switchMap(sortTypeLiveData, sort -> { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/comment/FetchComment.java b/app/src/main/java/eu/toldi/infinityforlemmy/comment/FetchComment.java index b7b7253e..9768f9c5 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/comment/FetchComment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/comment/FetchComment.java @@ -13,6 +13,7 @@ import java.util.concurrent.Executor; import eu.toldi.infinityforlemmy.SortType; import eu.toldi.infinityforlemmy.apis.LemmyAPI; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -22,19 +23,20 @@ public class FetchComment { public static void fetchComments(Executor executor, Handler handler, Retrofit retrofit, @Nullable String accessToken, Integer article, Integer commentId, SortType.Type sortType, boolean expandChildren, - Integer page, FetchCommentListener fetchCommentListener) { + Integer page, CommentFilter commentFilter, FetchCommentListener fetchCommentListener) { LemmyAPI api = retrofit.create(LemmyAPI.class); Call comments; comments = api.getComments("All", sortType.value, 8, page, 25, null, null, article, commentId, false, accessToken); - comments.enqueue(new Callback() { + comments.enqueue(new Callback<>() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { if (response.isSuccessful()) { ParseComment.parseComments(executor, handler, response.body(), commentId, - expandChildren, new ParseComment.ParseCommentListener() { + expandChildren, commentFilter, + new ParseComment.ParseCommentListener() { @Override public void onParseCommentSuccess(ArrayList topLevelComments, ArrayList expandedComments, @@ -70,7 +72,7 @@ public class FetchComment { moreComments = api.getComments("All", sortType.value, 8, page, 25, null, null, article, commentId, false, accessToken); - moreComments.enqueue(new Callback() { + moreComments.enqueue(new Callback<>() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { if (response.isSuccessful()) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/comment/ParseComment.java b/app/src/main/java/eu/toldi/infinityforlemmy/comment/ParseComment.java index bc913de1..fec0e9c2 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/comment/ParseComment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/comment/ParseComment.java @@ -24,14 +24,14 @@ import java.util.TimeZone; import java.util.concurrent.Executor; import java.util.regex.Pattern; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; import eu.toldi.infinityforlemmy.user.BasicUserInfo; import eu.toldi.infinityforlemmy.utils.JSONUtils; import eu.toldi.infinityforlemmy.utils.LemmyUtils; - public class ParseComment { public static void parseComments(Executor executor, Handler handler, String response, Integer commentId, - boolean expandChildren, + boolean expandChildren, CommentFilter commentFilter, ParseCommentListener parseCommentListener) { executor.execute(() -> { try { @@ -50,6 +50,9 @@ public class ParseComment { orderedComments.add(singleComment); parsedComments.put(singleComment.getId(), singleComment); if (singleComment.getDepth() == 0) { + if (!CommentFilter.isCommentAllowed(singleComment, commentFilter)) { + continue; + } topLevelComments.add(singleComment); } } @@ -58,7 +61,9 @@ public class ParseComment { if (parentComment.getDepth() == 0) { parentComment = null; } else { - expandedNewComments.add(parentComment); + if (CommentFilter.isCommentAllowed(parentComment, commentFilter)) { + expandedNewComments.add(parentComment); + } } } @@ -68,6 +73,9 @@ public class ParseComment { if (c.getParentId() != null) { Comment parent = parsedComments.get(c.getParentId()); if (parent != null) { + if (!CommentFilter.isCommentAllowed(c, commentFilter)) { + continue; + } parent.addChild(c); } } @@ -81,8 +89,13 @@ public class ParseComment { if (topLevelComments.isEmpty() && !parsedComments.isEmpty() && parentComment != null) { for (int i = 0; i < orderedComments.size(); i++) { Comment c = orderedComments.get(i); - if (c.getParentId() == parentComment.getId()) + if (c.getParentId() == parentComment.getId()) { + if (!CommentFilter.isCommentAllowed(c, commentFilter)) { + continue; + } expandedNewComments.add(c); + } + } } @@ -205,7 +218,8 @@ public class ParseComment { } private static void parseCommentRecursion(JSONArray comments, ArrayList newCommentData, - ArrayList moreChildrenIds, int depth) throws JSONException { + ArrayList moreChildrenIds, int depth, + CommentFilter commentFilter) throws JSONException { int actualCommentLength; if (comments.length() == 0) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilter.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilter.java new file mode 100644 index 00000000..7e0f8cc9 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilter.java @@ -0,0 +1,122 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +import java.util.List; + +import eu.toldi.infinityforlemmy.comment.Comment; + + +@Entity(tableName = "comment_filter") +public class CommentFilter implements Parcelable { + @PrimaryKey + @NonNull + public String name = "New Filter"; + @ColumnInfo(name = "max_vote") + public int maxVote = -1; + @ColumnInfo(name = "min_vote") + public int minVote = -1; + @ColumnInfo(name = "exclude_strings") + public String excludeStrings; + @ColumnInfo(name = "exclude_users") + public String excludeUsers; + + public CommentFilter() { + + } + + protected CommentFilter(Parcel in) { + name = in.readString(); + maxVote = in.readInt(); + minVote = in.readInt(); + excludeStrings = in.readString(); + excludeUsers = in.readString(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public CommentFilter createFromParcel(Parcel in) { + return new CommentFilter(in); + } + + @Override + public CommentFilter[] newArray(int size) { + return new CommentFilter[size]; + } + }; + + public static boolean isCommentAllowed(Comment comment, CommentFilter commentFilter) { + if (commentFilter.maxVote > 0 && comment.getVoteType() + comment.getScore() > commentFilter.maxVote) { + return false; + } + if (commentFilter.minVote > 0 && comment.getVoteType() + comment.getScore() < commentFilter.minVote) { + return false; + } + if (commentFilter.excludeStrings != null && !commentFilter.excludeStrings.equals("")) { + String[] titles = commentFilter.excludeStrings.split(",", 0); + for (String t : titles) { + if (!t.trim().equals("") && comment.getCommentRawText().toLowerCase().contains(t.toLowerCase().trim())) { + return false; + } + } + } + if (commentFilter.excludeUsers != null && !commentFilter.excludeUsers.equals("")) { + String[] users = commentFilter.excludeUsers.split(",", 0); + for (String u : users) { + if (!u.trim().equals("") && comment.getAuthor().getQualifiedName().equalsIgnoreCase(u.trim())) { + return false; + } + } + } + + return true; + } + + public static CommentFilter mergeCommentFilter(List commentFilterList) { + if (commentFilterList.size() == 1) { + return commentFilterList.get(0); + } + CommentFilter commentFilter = new CommentFilter(); + StringBuilder stringBuilder; + commentFilter.name = "Merged"; + + for (CommentFilter c : commentFilterList) { + commentFilter.maxVote = Math.min(c.maxVote, commentFilter.maxVote); + commentFilter.minVote = Math.max(c.minVote, commentFilter.minVote); + + if (c.excludeStrings != null && !c.excludeStrings.equals("")) { + stringBuilder = new StringBuilder(commentFilter.excludeStrings == null ? "" : commentFilter.excludeStrings); + stringBuilder.append(",").append(c.excludeStrings); + commentFilter.excludeStrings = stringBuilder.toString(); + } + + if (c.excludeUsers != null && !c.excludeUsers.equals("")) { + stringBuilder = new StringBuilder(commentFilter.excludeUsers == null ? "" : commentFilter.excludeUsers); + stringBuilder.append(",").append(c.excludeUsers); + commentFilter.excludeUsers = stringBuilder.toString(); + } + } + + return commentFilter; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(name); + dest.writeInt(maxVote); + dest.writeInt(minVote); + dest.writeString(excludeStrings); + dest.writeString(excludeUsers); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterDao.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterDao.java new file mode 100644 index 00000000..c205dabb --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterDao.java @@ -0,0 +1,47 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; +import androidx.room.Transaction; + +import java.util.List; + +@Dao +public interface CommentFilterDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(CommentFilter CommentFilter); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insertAll(List CommentFilters); + + @Query("DELETE FROM comment_filter") + void deleteAllCommentFilters(); + + @Delete + void deleteCommentFilter(CommentFilter CommentFilter); + + @Query("DELETE FROM comment_filter WHERE name = :name") + void deleteCommentFilter(String name); + + @Query("SELECT * FROM comment_filter WHERE name = :name LIMIT 1") + CommentFilter getCommentFilter(String name); + + @Query("SELECT * FROM comment_filter ORDER BY name") + LiveData> getAllCommentFiltersLiveData(); + + @Query("SELECT * FROM comment_filter") + List getAllCommentFilters(); + + @Query("SELECT * FROM comment_filter WHERE (comment_filter.name IN " + + "(SELECT comment_filter_usage.name FROM comment_filter_usage WHERE (usage = :usage AND name_of_usage = :nameOfUsage COLLATE NOCASE)))" + + " OR (comment_filter.name NOT IN (SELECT comment_filter_usage.name FROM comment_filter_usage))") + List getValidCommentFilters(int usage, String nameOfUsage); + + @Transaction + @Query("SELECT * FROM comment_filter ORDER BY name") + public LiveData> getAllCommentFilterWithUsageLiveData(); +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsage.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsage.java new file mode 100644 index 00000000..1cef93b1 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsage.java @@ -0,0 +1,61 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.ForeignKey; + +@Entity(tableName = "comment_filter_usage", primaryKeys = {"name", "usage", "name_of_usage"}, + foreignKeys = @ForeignKey(entity = CommentFilter.class, parentColumns = "name", + childColumns = "name", onDelete = ForeignKey.CASCADE)) +public class CommentFilterUsage implements Parcelable { + public static final int SUBREDDIT_TYPE = 1; + + @NonNull + @ColumnInfo(name = "name") + public String name; + @ColumnInfo(name = "usage") + public int usage; + @NonNull + @ColumnInfo(name = "name_of_usage") + public String nameOfUsage; + + public CommentFilterUsage(@NonNull String name, int usage, @NonNull String nameOfUsage) { + this.name = name; + this.usage = usage; + this.nameOfUsage = nameOfUsage; + } + + protected CommentFilterUsage(Parcel in) { + name = in.readString(); + usage = in.readInt(); + nameOfUsage = in.readString(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public CommentFilterUsage createFromParcel(Parcel in) { + return new CommentFilterUsage(in); + } + + @Override + public CommentFilterUsage[] newArray(int size) { + return new CommentFilterUsage[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(name); + dest.writeInt(usage); + dest.writeString(nameOfUsage); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageDao.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageDao.java new file mode 100644 index 00000000..6b89ab70 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageDao.java @@ -0,0 +1,31 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface CommentFilterUsageDao { + @Query("SELECT * FROM comment_filter_usage WHERE name = :name") + LiveData> getAllCommentFilterUsageLiveData(String name); + + @Query("SELECT * FROM comment_filter_usage WHERE name = :name") + List getAllCommentFilterUsage(String name); + + @Query("SELECT * FROM comment_filter_usage") + List getAllCommentFilterUsageForBackup(); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(CommentFilterUsage CommentFilterUsage); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insertAll(List CommentFilterUsageList); + + @Delete + void deleteCommentFilterUsage(CommentFilterUsage CommentFilterUsage); +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageViewModel.java new file mode 100644 index 00000000..83711ed4 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterUsageViewModel.java @@ -0,0 +1,41 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; + + +public class CommentFilterUsageViewModel extends ViewModel { + private LiveData> mCommentFilterUsageListLiveData; + + public CommentFilterUsageViewModel(RedditDataRoomDatabase redditDataRoomDatabase, String name) { + mCommentFilterUsageListLiveData = redditDataRoomDatabase.commentFilterUsageDao().getAllCommentFilterUsageLiveData(name); + } + + public LiveData> getCommentFilterUsageListLiveData() { + return mCommentFilterUsageListLiveData; + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + + private final RedditDataRoomDatabase mRedditDataRoomDatabase; + private final String mName; + + public Factory(RedditDataRoomDatabase redditDataRoomDatabase, String name) { + mRedditDataRoomDatabase = redditDataRoomDatabase; + mName = name; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + //noinspection unchecked + return (T) new CommentFilterUsageViewModel(mRedditDataRoomDatabase, mName); + } + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsage.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsage.java new file mode 100644 index 00000000..8b8d9793 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsage.java @@ -0,0 +1,16 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import androidx.room.Embedded; +import androidx.room.Relation; + +import java.util.List; + +public class CommentFilterWithUsage { + @Embedded + public CommentFilter commentFilter; + @Relation( + parentColumn = "name", + entityColumn = "name" + ) + public List commentFilterUsageList; +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsageViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsageViewModel.java new file mode 100644 index 00000000..2a814441 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/CommentFilterWithUsageViewModel.java @@ -0,0 +1,39 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; + + +public class CommentFilterWithUsageViewModel extends ViewModel { + private LiveData> mCommentFilterWithUsageListLiveData; + + public CommentFilterWithUsageViewModel(RedditDataRoomDatabase redditDataRoomDatabase) { + mCommentFilterWithUsageListLiveData = redditDataRoomDatabase.commentFilterDao().getAllCommentFilterWithUsageLiveData(); + } + + public LiveData> getCommentFilterWithUsageListLiveData() { + return mCommentFilterWithUsageListLiveData; + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + + private final RedditDataRoomDatabase mRedditDataRoomDatabase; + + public Factory(RedditDataRoomDatabase redditDataRoomDatabase) { + mRedditDataRoomDatabase = redditDataRoomDatabase; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + //noinspection unchecked + return (T) new CommentFilterWithUsageViewModel(mRedditDataRoomDatabase); + } + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilter.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilter.java new file mode 100644 index 00000000..21c5c2b4 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilter.java @@ -0,0 +1,12 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import java.util.concurrent.Executor; + +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; + + +public class DeleteCommentFilter { + public static void deleteCommentFilter(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, CommentFilter commentFilter) { + executor.execute(() -> redditDataRoomDatabase.commentFilterDao().deleteCommentFilter(commentFilter)); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilterUsage.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilterUsage.java new file mode 100644 index 00000000..bd183d55 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/DeleteCommentFilterUsage.java @@ -0,0 +1,13 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import java.util.concurrent.Executor; + +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; + + +public class DeleteCommentFilterUsage { + public static void deleteCommentFilterUsage(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, + CommentFilterUsage commentFilterUsage) { + executor.execute(() -> redditDataRoomDatabase.commentFilterUsageDao().deleteCommentFilterUsage(commentFilterUsage)); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/FetchCommentFilter.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/FetchCommentFilter.java new file mode 100644 index 00000000..6b01fbe3 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/FetchCommentFilter.java @@ -0,0 +1,25 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import android.os.Handler; + +import java.util.List; +import java.util.concurrent.Executor; + +;import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; + +public class FetchCommentFilter { + public static void fetchCommentFilter(Executor executor, Handler handler, + RedditDataRoomDatabase redditDataRoomDatabase, + String subreddit, FetchCommentFilterListener fetchCommentFilterListener) { + executor.execute(() -> { + List commentFilterList = redditDataRoomDatabase.commentFilterDao().getValidCommentFilters(CommentFilterUsage.SUBREDDIT_TYPE, subreddit); + CommentFilter commentFilter = CommentFilter.mergeCommentFilter(commentFilterList); + + handler.post(() -> fetchCommentFilterListener.success(commentFilter)); + }); + } + + public interface FetchCommentFilterListener { + void success(CommentFilter commentFilter); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilter.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilter.java new file mode 100644 index 00000000..7ccd66c6 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilter.java @@ -0,0 +1,38 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import android.os.Handler; + +import java.util.List; +import java.util.concurrent.Executor; + +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; + + +public class SaveCommentFilter { + public interface SaveCommentFilterListener { + void success(); + + void duplicate(); + } + + public static void saveCommentFilter(Executor executor, Handler handler, RedditDataRoomDatabase redditDataRoomDatabase, + CommentFilter commentFilter, String originalName, SaveCommentFilter.SaveCommentFilterListener saveCommentFilterListener) { + executor.execute(() -> { + if (!originalName.equals(commentFilter.name) && + redditDataRoomDatabase.commentFilterDao().getCommentFilter(commentFilter.name) != null) { + handler.post(saveCommentFilterListener::duplicate); + } else { + List commentFilterUsages = redditDataRoomDatabase.commentFilterUsageDao().getAllCommentFilterUsage(originalName); + if (!originalName.equals(commentFilter.name)) { + redditDataRoomDatabase.commentFilterDao().deleteCommentFilter(originalName); + } + redditDataRoomDatabase.commentFilterDao().insert(commentFilter); + for (CommentFilterUsage commentFilterUsage : commentFilterUsages) { + commentFilterUsage.name = commentFilter.name; + redditDataRoomDatabase.commentFilterUsageDao().insert(commentFilterUsage); + } + handler.post(saveCommentFilterListener::success); + } + }); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilterUsage.java b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilterUsage.java new file mode 100644 index 00000000..286fcf32 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/commentfilter/SaveCommentFilterUsage.java @@ -0,0 +1,13 @@ +package eu.toldi.infinityforlemmy.commentfilter; + +import java.util.concurrent.Executor; + +import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; + + +public class SaveCommentFilterUsage { + public static void saveCommentFilterUsage(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, + CommentFilterUsage commentFilterUsage) { + executor.execute(() -> redditDataRoomDatabase.commentFilterUsageDao().insert(commentFilterUsage)); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomTheme.java b/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomTheme.java index 7b6793c9..607c54ca 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomTheme.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomTheme.java @@ -64,6 +64,10 @@ public class CustomTheme { public int cardViewBackgroundColor; @ColumnInfo(name = "read_post_card_view_background_color") public int readPostCardViewBackgroundColor; + @ColumnInfo(name = "filled_card_view_background_color") + public int filledCardViewBackgroundColor; + @ColumnInfo(name = "read_post_filled_card_view_background_color") + public int readPostFilledCardViewBackgroundColor; @ColumnInfo(name = "comment_background_color") public int commentBackgroundColor; @ColumnInfo(name = "bottom_app_bar_background_color") @@ -255,71 +259,73 @@ public class CustomTheme { customTheme.backgroundColor = customThemeSettingsItems.get(19).colorValue; customTheme.cardViewBackgroundColor = customThemeSettingsItems.get(20).colorValue; customTheme.readPostCardViewBackgroundColor = customThemeSettingsItems.get(21).colorValue; - customTheme.commentBackgroundColor = customThemeSettingsItems.get(22).colorValue; - customTheme.fullyCollapsedCommentBackgroundColor = customThemeSettingsItems.get(23).colorValue; - customTheme.awardedCommentBackgroundColor = customThemeSettingsItems.get(24).colorValue; - customTheme.receivedMessageBackgroundColor = customThemeSettingsItems.get(25).colorValue; - customTheme.sentMessageBackgroundColor = customThemeSettingsItems.get(26).colorValue; - customTheme.bottomAppBarBackgroundColor = customThemeSettingsItems.get(27).colorValue; - customTheme.primaryIconColor = customThemeSettingsItems.get(28).colorValue; - customTheme.bottomAppBarIconColor = customThemeSettingsItems.get(29).colorValue; - customTheme.postIconAndInfoColor = customThemeSettingsItems.get(30).colorValue; - customTheme.commentIconAndInfoColor = customThemeSettingsItems.get(31).colorValue; - customTheme.fabIconColor = customThemeSettingsItems.get(32).colorValue; - customTheme.sendMessageIconColor = customThemeSettingsItems.get(33).colorValue; - customTheme.toolbarPrimaryTextAndIconColor = customThemeSettingsItems.get(34).colorValue; - customTheme.toolbarSecondaryTextColor = customThemeSettingsItems.get(35).colorValue; - customTheme.circularProgressBarBackground = customThemeSettingsItems.get(36).colorValue; - customTheme.mediaIndicatorIconColor = customThemeSettingsItems.get(37).colorValue; - customTheme.mediaIndicatorBackgroundColor = customThemeSettingsItems.get(38).colorValue; - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = customThemeSettingsItems.get(39).colorValue; - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = customThemeSettingsItems.get(40).colorValue; - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(41).colorValue; - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = customThemeSettingsItems.get(42).colorValue; - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = customThemeSettingsItems.get(43).colorValue; - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(44).colorValue; - customTheme.upvoted = customThemeSettingsItems.get(45).colorValue; - customTheme.downvoted = customThemeSettingsItems.get(46).colorValue; - customTheme.postTypeBackgroundColor = customThemeSettingsItems.get(47).colorValue; - customTheme.postTypeTextColor = customThemeSettingsItems.get(48).colorValue; - customTheme.spoilerBackgroundColor = customThemeSettingsItems.get(49).colorValue; - customTheme.spoilerTextColor = customThemeSettingsItems.get(50).colorValue; - customTheme.nsfwBackgroundColor = customThemeSettingsItems.get(51).colorValue; - customTheme.nsfwTextColor = customThemeSettingsItems.get(52).colorValue; - customTheme.flairBackgroundColor = customThemeSettingsItems.get(53).colorValue; - customTheme.flairTextColor = customThemeSettingsItems.get(54).colorValue; - customTheme.awardsBackgroundColor = customThemeSettingsItems.get(55).colorValue; - customTheme.awardsTextColor = customThemeSettingsItems.get(56).colorValue; - customTheme.archivedTint = customThemeSettingsItems.get(57).colorValue; - customTheme.lockedIconTint = customThemeSettingsItems.get(58).colorValue; - customTheme.crosspostIconTint = customThemeSettingsItems.get(59).colorValue; - customTheme.upvoteRatioIconTint = customThemeSettingsItems.get(60).colorValue; - customTheme.stickiedPostIconTint = customThemeSettingsItems.get(61).colorValue; - customTheme.noPreviewPostTypeIconTint = customThemeSettingsItems.get(62).colorValue; - customTheme.subscribed = customThemeSettingsItems.get(63).colorValue; - customTheme.unsubscribed = customThemeSettingsItems.get(64).colorValue; - customTheme.username = customThemeSettingsItems.get(65).colorValue; - customTheme.subreddit = customThemeSettingsItems.get(66).colorValue; - customTheme.authorFlairTextColor = customThemeSettingsItems.get(67).colorValue; - customTheme.submitter = customThemeSettingsItems.get(68).colorValue; - customTheme.moderator = customThemeSettingsItems.get(69).colorValue; - customTheme.currentUser = customThemeSettingsItems.get(70).colorValue; - customTheme.singleCommentThreadBackgroundColor = customThemeSettingsItems.get(71).colorValue; - customTheme.unreadMessageBackgroundColor = customThemeSettingsItems.get(72).colorValue; - customTheme.dividerColor = customThemeSettingsItems.get(73).colorValue; - customTheme.noPreviewPostTypeBackgroundColor = customThemeSettingsItems.get(74).colorValue; - customTheme.voteAndReplyUnavailableButtonColor = customThemeSettingsItems.get(75).colorValue; - customTheme.commentVerticalBarColor1 = customThemeSettingsItems.get(76).colorValue; - customTheme.commentVerticalBarColor2 = customThemeSettingsItems.get(77).colorValue; - customTheme.commentVerticalBarColor3 = customThemeSettingsItems.get(78).colorValue; - customTheme.commentVerticalBarColor4 = customThemeSettingsItems.get(79).colorValue; - customTheme.commentVerticalBarColor5 = customThemeSettingsItems.get(80).colorValue; - customTheme.commentVerticalBarColor6 = customThemeSettingsItems.get(81).colorValue; - customTheme.commentVerticalBarColor7 = customThemeSettingsItems.get(82).colorValue; - customTheme.navBarColor = customThemeSettingsItems.get(83).colorValue; - customTheme.isLightStatusBar = customThemeSettingsItems.get(84).isEnabled; - customTheme.isLightNavBar = customThemeSettingsItems.get(85).isEnabled; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = customThemeSettingsItems.get(86).isEnabled; + customTheme.filledCardViewBackgroundColor = customThemeSettingsItems.get(22).colorValue; + customTheme.readPostFilledCardViewBackgroundColor = customThemeSettingsItems.get(23).colorValue; + customTheme.commentBackgroundColor = customThemeSettingsItems.get(24).colorValue; + customTheme.fullyCollapsedCommentBackgroundColor = customThemeSettingsItems.get(25).colorValue; + customTheme.awardedCommentBackgroundColor = customThemeSettingsItems.get(26).colorValue; + customTheme.receivedMessageBackgroundColor = customThemeSettingsItems.get(27).colorValue; + customTheme.sentMessageBackgroundColor = customThemeSettingsItems.get(28).colorValue; + customTheme.bottomAppBarBackgroundColor = customThemeSettingsItems.get(29).colorValue; + customTheme.primaryIconColor = customThemeSettingsItems.get(30).colorValue; + customTheme.bottomAppBarIconColor = customThemeSettingsItems.get(31).colorValue; + customTheme.postIconAndInfoColor = customThemeSettingsItems.get(32).colorValue; + customTheme.commentIconAndInfoColor = customThemeSettingsItems.get(33).colorValue; + customTheme.fabIconColor = customThemeSettingsItems.get(34).colorValue; + customTheme.sendMessageIconColor = customThemeSettingsItems.get(35).colorValue; + customTheme.toolbarPrimaryTextAndIconColor = customThemeSettingsItems.get(36).colorValue; + customTheme.toolbarSecondaryTextColor = customThemeSettingsItems.get(37).colorValue; + customTheme.circularProgressBarBackground = customThemeSettingsItems.get(38).colorValue; + customTheme.mediaIndicatorIconColor = customThemeSettingsItems.get(39).colorValue; + customTheme.mediaIndicatorBackgroundColor = customThemeSettingsItems.get(40).colorValue; + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = customThemeSettingsItems.get(41).colorValue; + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = customThemeSettingsItems.get(42).colorValue; + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(43).colorValue; + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = customThemeSettingsItems.get(44).colorValue; + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = customThemeSettingsItems.get(45).colorValue; + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(46).colorValue; + customTheme.upvoted = customThemeSettingsItems.get(47).colorValue; + customTheme.downvoted = customThemeSettingsItems.get(48).colorValue; + customTheme.postTypeBackgroundColor = customThemeSettingsItems.get(49).colorValue; + customTheme.postTypeTextColor = customThemeSettingsItems.get(50).colorValue; + customTheme.spoilerBackgroundColor = customThemeSettingsItems.get(51).colorValue; + customTheme.spoilerTextColor = customThemeSettingsItems.get(52).colorValue; + customTheme.nsfwBackgroundColor = customThemeSettingsItems.get(53).colorValue; + customTheme.nsfwTextColor = customThemeSettingsItems.get(54).colorValue; + customTheme.flairBackgroundColor = customThemeSettingsItems.get(55).colorValue; + customTheme.flairTextColor = customThemeSettingsItems.get(56).colorValue; + customTheme.awardsBackgroundColor = customThemeSettingsItems.get(57).colorValue; + customTheme.awardsTextColor = customThemeSettingsItems.get(58).colorValue; + customTheme.archivedTint = customThemeSettingsItems.get(59).colorValue; + customTheme.lockedIconTint = customThemeSettingsItems.get(60).colorValue; + customTheme.crosspostIconTint = customThemeSettingsItems.get(61).colorValue; + customTheme.upvoteRatioIconTint = customThemeSettingsItems.get(62).colorValue; + customTheme.stickiedPostIconTint = customThemeSettingsItems.get(63).colorValue; + customTheme.noPreviewPostTypeIconTint = customThemeSettingsItems.get(64).colorValue; + customTheme.subscribed = customThemeSettingsItems.get(65).colorValue; + customTheme.unsubscribed = customThemeSettingsItems.get(66).colorValue; + customTheme.username = customThemeSettingsItems.get(67).colorValue; + customTheme.subreddit = customThemeSettingsItems.get(68).colorValue; + customTheme.authorFlairTextColor = customThemeSettingsItems.get(69).colorValue; + customTheme.submitter = customThemeSettingsItems.get(70).colorValue; + customTheme.moderator = customThemeSettingsItems.get(71).colorValue; + customTheme.currentUser = customThemeSettingsItems.get(72).colorValue; + customTheme.singleCommentThreadBackgroundColor = customThemeSettingsItems.get(73).colorValue; + customTheme.unreadMessageBackgroundColor = customThemeSettingsItems.get(74).colorValue; + customTheme.dividerColor = customThemeSettingsItems.get(75).colorValue; + customTheme.noPreviewPostTypeBackgroundColor = customThemeSettingsItems.get(76).colorValue; + customTheme.voteAndReplyUnavailableButtonColor = customThemeSettingsItems.get(77).colorValue; + customTheme.commentVerticalBarColor1 = customThemeSettingsItems.get(78).colorValue; + customTheme.commentVerticalBarColor2 = customThemeSettingsItems.get(79).colorValue; + customTheme.commentVerticalBarColor3 = customThemeSettingsItems.get(80).colorValue; + customTheme.commentVerticalBarColor4 = customThemeSettingsItems.get(81).colorValue; + customTheme.commentVerticalBarColor5 = customThemeSettingsItems.get(82).colorValue; + customTheme.commentVerticalBarColor6 = customThemeSettingsItems.get(83).colorValue; + customTheme.commentVerticalBarColor7 = customThemeSettingsItems.get(84).colorValue; + customTheme.navBarColor = customThemeSettingsItems.get(85).colorValue; + customTheme.isLightStatusBar = customThemeSettingsItems.get(86).isEnabled; + customTheme.isLightNavBar = customThemeSettingsItems.get(87).isEnabled; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = customThemeSettingsItems.get(88).isEnabled; return customTheme; } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeSettingsItem.java b/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeSettingsItem.java index f2e37dab..f97de20f 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeSettingsItem.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeSettingsItem.java @@ -144,6 +144,14 @@ public class CustomThemeSettingsItem implements Parcelable { context.getString(R.string.theme_item_read_post_card_view_background_color), context.getString(R.string.theme_item_read_post_card_view_background_color_detail), customTheme.readPostCardViewBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_filled_card_view_background_color), + context.getString(R.string.theme_item_filled_card_view_background_color_detail), + customTheme.filledCardViewBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_read_post_filled_card_view_background_color), + context.getString(R.string.theme_item_read_post_filled_card_view_background_color_detail), + customTheme.readPostFilledCardViewBackgroundColor)); customThemeSettingsItems.add(new CustomThemeSettingsItem( context.getString(R.string.theme_item_comment_background_color), context.getString(R.string.theme_item_comment_background_color_detail), diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeWrapper.java b/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeWrapper.java index bf4318f9..c25a95f9 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeWrapper.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/customtheme/CustomThemeWrapper.java @@ -127,6 +127,16 @@ public class CustomThemeWrapper { getDefaultColor("#F2E9E1", "#2B3B51", "#282828")); } + public int getFilledCardViewBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FILLED_CARD_VIEW_BACKGROUND_COLOR, + getDefaultColor("#E6F4FF", "#242424", "#000000")); + } + + public int getReadPostFilledCardViewBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.READ_POST_FILLED_CARD_VIEW_BACKGROUND_COLOR, + getDefaultColor("#F5F5F5", "#101010", "#000000")); + } + public int getCommentBackgroundColor() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_BACKGROUND_COLOR, getDefaultColor("#F6F2EE", "#192330", "#282828")); @@ -548,6 +558,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#FFFFFF"); customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#F5F5F5"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#E6F4FF"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#F5F5F5"); customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.primaryIconColor = Color.parseColor("#000000"); @@ -641,6 +653,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#121212"); customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#101010"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#242424"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#101010"); customTheme.commentBackgroundColor = Color.parseColor("#242424"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); @@ -734,6 +748,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#000000"); customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#000000"); customTheme.commentBackgroundColor = Color.parseColor("#000000"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); @@ -827,6 +843,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#FFFFFF"); customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#F5F5F5"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#E6F4FF"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#F5F5F5"); customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.primaryIconColor = Color.parseColor("#000000"); @@ -920,6 +938,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#121212"); customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#101010"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#242424"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#101010"); customTheme.commentBackgroundColor = Color.parseColor("#242424"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); @@ -1013,6 +1033,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#000000"); customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#000000"); customTheme.commentBackgroundColor = Color.parseColor("#000000"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); @@ -1106,6 +1128,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#FFFFFF"); customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#F5F5F5"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#FFE9F3"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#F5F5F5"); customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); customTheme.primaryIconColor = Color.parseColor("#000000"); @@ -1199,6 +1223,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#121212"); customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#101010"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#242424"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#101010"); customTheme.commentBackgroundColor = Color.parseColor("#242424"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); @@ -1292,6 +1318,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#000000"); customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#000000"); customTheme.commentBackgroundColor = Color.parseColor("#000000"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); @@ -1385,6 +1413,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#282A36"); customTheme.cardViewBackgroundColor = Color.parseColor("#393A59"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#1C1F3D"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#393A59"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#1C1F3D"); customTheme.commentBackgroundColor = Color.parseColor("#393A59"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#393A59"); customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); @@ -1478,6 +1508,8 @@ public class CustomThemeWrapper { customTheme.backgroundColor = Color.parseColor("#DAD0DE"); customTheme.cardViewBackgroundColor = Color.parseColor("#C0F0F4"); customTheme.readPostCardViewBackgroundColor = Color.parseColor("#D2E7EA"); + customTheme.filledCardViewBackgroundColor = Color.parseColor("#C0F0F4"); + customTheme.readPostFilledCardViewBackgroundColor = Color.parseColor("#D2E7EA"); customTheme.commentBackgroundColor = Color.parseColor("#C0F0F4"); customTheme.bottomAppBarBackgroundColor = Color.parseColor("#D48AE0"); customTheme.primaryIconColor = Color.parseColor("#000000"); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/customviews/InterceptTouchEventLinearLayout.java b/app/src/main/java/eu/toldi/infinityforlemmy/customviews/InterceptTouchEventLinearLayout.java new file mode 100644 index 00000000..4a4cc8f3 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/customviews/InterceptTouchEventLinearLayout.java @@ -0,0 +1,31 @@ +package eu.toldi.infinityforlemmy.customviews; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +public class InterceptTouchEventLinearLayout extends LinearLayout { + public InterceptTouchEventLinearLayout(Context context) { + super(context); + } + + public InterceptTouchEventLinearLayout(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public InterceptTouchEventLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return true; + } + + public InterceptTouchEventLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/customviews/slidr/widget/SliderPanel.java b/app/src/main/java/eu/toldi/infinityforlemmy/customviews/slidr/widget/SliderPanel.java index 37d43d08..ede3b3d9 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/customviews/slidr/widget/SliderPanel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/customviews/slidr/widget/SliderPanel.java @@ -389,7 +389,7 @@ public class SliderPanel extends FrameLayout { /** - * The drag helper callbacks for dragging the slidr attachment from the bottom of hte screen + * The drag helper callbacks for dragging the slidr attachment from the bottom of the screen */ private final ViewDragHelper.Callback bottomCallback = new ViewDragHelper.Callback() { @Override diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/CommentsListingFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/CommentsListingFragment.java index a68b2545..fa848964 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/CommentsListingFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/CommentsListingFragment.java @@ -154,7 +154,7 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni @Override public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { - if (!(viewHolder instanceof CommentsListingRecyclerViewAdapter.CommentViewHolder)) { + if (!(viewHolder instanceof CommentsListingRecyclerViewAdapter.CommentBaseViewHolder)) { return makeMovementFlags(0, 0); } int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java deleted file mode 100644 index 2645d6d6..00000000 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java +++ /dev/null @@ -1,1445 +0,0 @@ -package eu.toldi.infinityforlemmy.fragments; - -import static eu.toldi.infinityforlemmy.videoautoplay.media.PlaybackInfo.INDEX_UNSET; -import static eu.toldi.infinityforlemmy.videoautoplay.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.ItemSnapshotList; -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 org.greenrobot.eventbus.Subscribe; - -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 javax.inject.Provider; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.Unbinder; -import eu.toldi.infinityforlemmy.FetchPostFilterReadPostsAndConcatenatedSubredditNames; -import eu.toldi.infinityforlemmy.FragmentCommunicator; -import eu.toldi.infinityforlemmy.Infinity; -import eu.toldi.infinityforlemmy.R; -import eu.toldi.infinityforlemmy.RecyclerViewContentScrollingInterface; -import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; -import eu.toldi.infinityforlemmy.RetrofitHolder; -import eu.toldi.infinityforlemmy.activities.BaseActivity; -import eu.toldi.infinityforlemmy.adapters.HistoryPostRecyclerViewAdapter; -import eu.toldi.infinityforlemmy.adapters.Paging3LoadingStateAdapter; -import eu.toldi.infinityforlemmy.apis.StreamableAPI; -import eu.toldi.infinityforlemmy.asynctasks.LoadSubredditIcon; -import eu.toldi.infinityforlemmy.asynctasks.LoadUserData; -import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; -import eu.toldi.infinityforlemmy.customviews.CustomToroContainer; -import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; -import eu.toldi.infinityforlemmy.events.ChangeAutoplayNsfwVideosEvent; -import eu.toldi.infinityforlemmy.events.ChangeCompactLayoutToolbarHiddenByDefaultEvent; -import eu.toldi.infinityforlemmy.events.ChangeDataSavingModeEvent; -import eu.toldi.infinityforlemmy.events.ChangeDefaultLinkPostLayoutEvent; -import eu.toldi.infinityforlemmy.events.ChangeDefaultPostLayoutEvent; -import eu.toldi.infinityforlemmy.events.ChangeDisableImagePreviewEvent; -import eu.toldi.infinityforlemmy.events.ChangeEasierToWatchInFullScreenEvent; -import eu.toldi.infinityforlemmy.events.ChangeEnableSwipeActionSwitchEvent; -import eu.toldi.infinityforlemmy.events.ChangeFixedHeightPreviewInCardEvent; -import eu.toldi.infinityforlemmy.events.ChangeHidePostFlairEvent; -import eu.toldi.infinityforlemmy.events.ChangeHidePostTypeEvent; -import eu.toldi.infinityforlemmy.events.ChangeHideSubredditAndUserPrefixEvent; -import eu.toldi.infinityforlemmy.events.ChangeHideTextPostContent; -import eu.toldi.infinityforlemmy.events.ChangeHideTheNumberOfAwardsEvent; -import eu.toldi.infinityforlemmy.events.ChangeHideTheNumberOfCommentsEvent; -import eu.toldi.infinityforlemmy.events.ChangeHideTheNumberOfVotesEvent; -import eu.toldi.infinityforlemmy.events.ChangeLongPressToHideToolbarInCompactLayoutEvent; -import eu.toldi.infinityforlemmy.events.ChangeMuteAutoplayingVideosEvent; -import eu.toldi.infinityforlemmy.events.ChangeMuteNSFWVideoEvent; -import eu.toldi.infinityforlemmy.events.ChangeNSFWBlurEvent; -import eu.toldi.infinityforlemmy.events.ChangeNetworkStatusEvent; -import eu.toldi.infinityforlemmy.events.ChangeOnlyDisablePreviewInVideoAndGifPostsEvent; -import eu.toldi.infinityforlemmy.events.ChangePostFeedMaxResolutionEvent; -import eu.toldi.infinityforlemmy.events.ChangePostLayoutEvent; -import eu.toldi.infinityforlemmy.events.ChangePullToRefreshEvent; -import eu.toldi.infinityforlemmy.events.ChangeRememberMutingOptionInPostFeedEvent; -import eu.toldi.infinityforlemmy.events.ChangeShowAbsoluteNumberOfVotesEvent; -import eu.toldi.infinityforlemmy.events.ChangeShowElapsedTimeEvent; -import eu.toldi.infinityforlemmy.events.ChangeSpoilerBlurEvent; -import eu.toldi.infinityforlemmy.events.ChangeStartAutoplayVisibleAreaOffsetEvent; -import eu.toldi.infinityforlemmy.events.ChangeSwipeActionEvent; -import eu.toldi.infinityforlemmy.events.ChangeSwipeActionThresholdEvent; -import eu.toldi.infinityforlemmy.events.ChangeTimeFormatEvent; -import eu.toldi.infinityforlemmy.events.ChangeVibrateWhenActionTriggeredEvent; -import eu.toldi.infinityforlemmy.events.ChangeVideoAutoplayEvent; -import eu.toldi.infinityforlemmy.events.ChangeVoteButtonsPositionEvent; -import eu.toldi.infinityforlemmy.events.NeedForPostListFromPostFragmentEvent; -import eu.toldi.infinityforlemmy.events.PostUpdateEventToPostList; -import eu.toldi.infinityforlemmy.events.ProvidePostListToViewPostDetailActivityEvent; -import eu.toldi.infinityforlemmy.events.ShowDividerInCompactLayoutPreferenceEvent; -import eu.toldi.infinityforlemmy.events.ShowThumbnailOnTheRightInCompactLayoutEvent; -import eu.toldi.infinityforlemmy.post.HistoryPostPagingSource; -import eu.toldi.infinityforlemmy.post.HistoryPostViewModel; -import eu.toldi.infinityforlemmy.post.Post; -import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; -import eu.toldi.infinityforlemmy.postfilter.PostFilter; -import eu.toldi.infinityforlemmy.postfilter.PostFilterUsage; -import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; -import eu.toldi.infinityforlemmy.utils.Utils; -import eu.toldi.infinityforlemmy.videoautoplay.ExoCreator; -import eu.toldi.infinityforlemmy.videoautoplay.media.PlaybackInfo; -import eu.toldi.infinityforlemmy.videoautoplay.media.VolumeInfo; -import retrofit2.Retrofit; - -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") - RetrofitHolder mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("gfycat") - Retrofit mGfycatRetrofit; - @Inject - @Named("redgifs") - Retrofit mRedgifsRetrofit; - @Inject - Provider mStreamableApiProvider; - @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; - @Inject - PostEnricher postEnricher; - 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 swipeActionEnabled; - 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 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 readPosts; - private Unbinder unbinder; - private Map 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(mLinearLayoutManager.findFirstVisibleItemPosition()); - } else { - int[] into = new int[2]; - setCurrentPosition(mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[1]); - } - } - - if (getCurrentPosition() != RecyclerView.NO_POSITION && nPosts > getCurrentPosition()) { - incrementCurrentPosition(); - smoothScroller.setTargetPosition(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_READ_POST, defaultPostLayout); - - mAdapter = new HistoryPostRecyclerViewAdapter(activity, this, mExecutor, mRetrofit.getRetrofit(), mGfycatRetrofit, - mRedgifsRetrofit, mStreamableApiProvider, mCustomThemeWrapper, locale, - accessToken, accountName, postType, postLayout, true, - mSharedPreferences, mNsfwAndSpoilerSharedPreferences, - 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 HistoryPostRecyclerViewAdapter.PostBaseViewHolder) && - !(viewHolder instanceof HistoryPostRecyclerViewAdapter.PostCompactBaseViewHolder)) { - return makeMovementFlags(0, 0); - } else if (viewHolder instanceof HistoryPostRecyclerViewAdapter.PostBaseGalleryTypeViewHolder) { - if (((HistoryPostRecyclerViewAdapter.PostBaseGalleryTypeViewHolder) viewHolder).isSwipeLocked()) { - 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) { - exceedThreshold = false; - touchHelper.attachToRecyclerView(null); - touchHelper.attachToRecyclerView(mPostRecyclerView); - } - } - - @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); - - if (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); - } - } else { - if (exceedThreshold) { - mAdapter.onItemSwipe(viewHolder, dX > 0 ? ItemTouchHelper.END : ItemTouchHelper.START, swipeLeftAction, swipeRightAction); - exceedThreshold = false; - } - } - } - - @Override - public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { - return 1; - } - }); - - if (nColumns == 1 && mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false)) { - swipeActionEnabled = true; - 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) { - mHistoryPostViewModel = new ViewModelProvider(HistoryPostFragment.this, new HistoryPostViewModel.Factory(mExecutor, - accessToken == null ? mRetrofit.getRetrofit() : mOauthRetrofit, mRedditDataRoomDatabase, accessToken, - accountName, mSharedPreferences, HistoryPostPagingSource.TYPE_READ_POSTS, postFilter, postEnricher)) - .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_READ_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, mRetrofit.getRetrofit(), - iconImageUrl -> { - subredditOrUserIcons.put(subredditOrUserName, iconImageUrl); - loadIconListener.loadIconSuccess(subredditOrUserName, iconImageUrl); - }); - } else { - LoadUserData.loadUserData(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditOrUserName, - mRetrofit.getRetrofit(), 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); - } - } - - public boolean isRecyclerViewItemSwipeable(RecyclerView.ViewHolder viewHolder) { - if (swipeActionEnabled) { - if (viewHolder instanceof HistoryPostRecyclerViewAdapter.PostBaseGalleryTypeViewHolder) { - return !((HistoryPostRecyclerViewAdapter.PostBaseGalleryTypeViewHolder) viewHolder).isSwipeLocked(); - } - - return true; - } - - return false; - } - - @Subscribe - public void onPostUpdateEvent(PostUpdateEventToPostList event) { - ItemSnapshotList posts = mAdapter.snapshot(); - if (event.positionInList >= 0 && event.positionInList < posts.size()) { - Post post = posts.get(event.positionInList); - if (post != null && post.getFullName().equals(event.post.getFullName())) { - post.setTitle(event.post.getTitle()); - post.setVoteType(event.post.getVoteType()); - post.setDownvotes(event.post.getDownvotes()); - post.setUpvotes(event.post.getUpvotes()); - post.setNComments(event.post.getNComments()); - post.setNSFW(event.post.isNSFW()); - post.setHidden(event.post.isHidden()); - post.setSaved(event.post.isSaved()); - if (event.post.isRead()) { - post.markAsRead(); - } - mAdapter.notifyItemChanged(event.positionInList); - } - } - } - - @Subscribe - public void onChangeShowElapsedTimeEvent(ChangeShowElapsedTimeEvent event) { - if (mAdapter != null) { - mAdapter.setShowElapsedTime(event.showElapsedTime); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeTimeFormatEvent(ChangeTimeFormatEvent changeTimeFormatEvent) { - if (mAdapter != null) { - mAdapter.setTimeFormat(changeTimeFormatEvent.timeFormat); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeVoteButtonsPositionEvent(ChangeVoteButtonsPositionEvent event) { - if (mAdapter != null) { - mAdapter.setVoteButtonsPosition(event.voteButtonsOnTheRight); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeNSFWBlurEvent(ChangeNSFWBlurEvent event) { - if (mAdapter != null) { - mAdapter.setBlurNsfwAndDoNotBlurNsfwInNsfwSubreddits(event.needBlurNSFW); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeSpoilerBlurEvent(ChangeSpoilerBlurEvent event) { - if (mAdapter != null) { - mAdapter.setBlurSpoiler(event.needBlurSpoiler); - refreshAdapter(); - } - } - - @Subscribe - public void onChangePostLayoutEvent(ChangePostLayoutEvent event) { - changePostLayout(event.postLayout); - } - - @Subscribe - public void onShowDividerInCompactLayoutPreferenceEvent(ShowDividerInCompactLayoutPreferenceEvent event) { - if (mAdapter != null) { - mAdapter.setShowDividerInCompactLayout(event.showDividerInCompactLayout); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeDefaultPostLayoutEvent(ChangeDefaultPostLayoutEvent changeDefaultPostLayoutEvent) { - Bundle bundle = getArguments(); - if (bundle != null) { - switch (postType) { - case HistoryPostPagingSource.TYPE_READ_POSTS: - if (mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.HISTORY_POST_LAYOUT_READ_POST)) { - changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout, true); - } - break; - } - } - } - - @Subscribe - public void onChangeDefaultLinkPostLayoutEvent(ChangeDefaultLinkPostLayoutEvent event) { - if (mAdapter != null) { - mAdapter.setDefaultLinkPostLayout(event.defaultLinkPostLayout); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeShowAbsoluteNumberOfVotesEvent(ChangeShowAbsoluteNumberOfVotesEvent changeShowAbsoluteNumberOfVotesEvent) { - if (mAdapter != null) { - mAdapter.setShowAbsoluteNumberOfVotes(changeShowAbsoluteNumberOfVotesEvent.showAbsoluteNumberOfVotes); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeVideoAutoplayEvent(ChangeVideoAutoplayEvent changeVideoAutoplayEvent) { - if (mAdapter != null) { - boolean autoplay = false; - if (changeVideoAutoplayEvent.autoplay.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ALWAYS_ON)) { - autoplay = true; - } else if (changeVideoAutoplayEvent.autoplay.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ON_WIFI)) { - autoplay = Utils.isConnectedToWifi(activity); - } - mAdapter.setAutoplay(autoplay); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeAutoplayNsfwVideosEvent(ChangeAutoplayNsfwVideosEvent changeAutoplayNsfwVideosEvent) { - if (mAdapter != null) { - mAdapter.setAutoplayNsfwVideos(changeAutoplayNsfwVideosEvent.autoplayNsfwVideos); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeMuteAutoplayingVideosEvent(ChangeMuteAutoplayingVideosEvent changeMuteAutoplayingVideosEvent) { - if (mAdapter != null) { - mAdapter.setMuteAutoplayingVideos(changeMuteAutoplayingVideosEvent.muteAutoplayingVideos); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeNetworkStatusEvent(ChangeNetworkStatusEvent changeNetworkStatusEvent) { - if (mAdapter != null) { - String autoplay = mSharedPreferences.getString(SharedPreferencesUtils.VIDEO_AUTOPLAY, SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_NEVER); - String dataSavingMode = mSharedPreferences.getString(SharedPreferencesUtils.DATA_SAVING_MODE, SharedPreferencesUtils.DATA_SAVING_MODE_OFF); - boolean stateChanged = false; - if (autoplay.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ON_WIFI)) { - mAdapter.setAutoplay(changeNetworkStatusEvent.connectedNetwork == Utils.NETWORK_TYPE_WIFI); - stateChanged = true; - } - if (dataSavingMode.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA)) { - mAdapter.setDataSavingMode(changeNetworkStatusEvent.connectedNetwork == Utils.NETWORK_TYPE_CELLULAR); - stateChanged = true; - } - - if (stateChanged) { - refreshAdapter(); - } - } - } - - @Subscribe - public void onShowThumbnailOnTheRightInCompactLayoutEvent(ShowThumbnailOnTheRightInCompactLayoutEvent showThumbnailOnTheRightInCompactLayoutEvent) { - if (mAdapter != null) { - mAdapter.setShowThumbnailOnTheRightInCompactLayout(showThumbnailOnTheRightInCompactLayoutEvent.showThumbnailOnTheRightInCompactLayout); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeStartAutoplayVisibleAreaOffsetEvent(ChangeStartAutoplayVisibleAreaOffsetEvent changeStartAutoplayVisibleAreaOffsetEvent) { - if (mAdapter != null) { - mAdapter.setStartAutoplayVisibleAreaOffset(changeStartAutoplayVisibleAreaOffsetEvent.startAutoplayVisibleAreaOffset); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeMuteNSFWVideoEvent(ChangeMuteNSFWVideoEvent changeMuteNSFWVideoEvent) { - if (mAdapter != null) { - mAdapter.setMuteNSFWVideo(changeMuteNSFWVideoEvent.muteNSFWVideo); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeVibrateWhenActionTriggeredEvent(ChangeVibrateWhenActionTriggeredEvent changeVibrateWhenActionTriggeredEvent) { - vibrateWhenActionTriggered = changeVibrateWhenActionTriggeredEvent.vibrateWhenActionTriggered; - } - - @Subscribe - public void onChangeEnableSwipeActionSwitchEvent(ChangeEnableSwipeActionSwitchEvent changeEnableSwipeActionSwitchEvent) { - if (getNColumns(getResources()) == 1 && touchHelper != null) { - swipeActionEnabled = changeEnableSwipeActionSwitchEvent.enableSwipeAction; - if (changeEnableSwipeActionSwitchEvent.enableSwipeAction) { - touchHelper.attachToRecyclerView(mPostRecyclerView); - } else { - touchHelper.attachToRecyclerView(null); - } - } - } - - @Subscribe - public void onChangePullToRefreshEvent(ChangePullToRefreshEvent changePullToRefreshEvent) { - mSwipeRefreshLayout.setEnabled(changePullToRefreshEvent.pullToRefresh); - } - - @Subscribe - public void onChangeLongPressToHideToolbarInCompactLayoutEvent(ChangeLongPressToHideToolbarInCompactLayoutEvent changeLongPressToHideToolbarInCompactLayoutEvent) { - if (mAdapter != null) { - mAdapter.setLongPressToHideToolbarInCompactLayout(changeLongPressToHideToolbarInCompactLayoutEvent.longPressToHideToolbarInCompactLayout); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeCompactLayoutToolbarHiddenByDefaultEvent(ChangeCompactLayoutToolbarHiddenByDefaultEvent changeCompactLayoutToolbarHiddenByDefaultEvent) { - if (mAdapter != null) { - mAdapter.setCompactLayoutToolbarHiddenByDefault(changeCompactLayoutToolbarHiddenByDefaultEvent.compactLayoutToolbarHiddenByDefault); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeSwipeActionThresholdEvent(ChangeSwipeActionThresholdEvent changeSwipeActionThresholdEvent) { - swipeActionThreshold = changeSwipeActionThresholdEvent.swipeActionThreshold; - } - - @Subscribe - public void onChangeDataSavingModeEvent(ChangeDataSavingModeEvent changeDataSavingModeEvent) { - if (mAdapter != null) { - boolean dataSavingMode = false; - if (changeDataSavingModeEvent.dataSavingMode.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA)) { - dataSavingMode = Utils.isConnectedToCellularData(activity); - } else if (changeDataSavingModeEvent.dataSavingMode.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ALWAYS)) { - dataSavingMode = true; - } - mAdapter.setDataSavingMode(dataSavingMode); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeDisableImagePreviewEvent(ChangeDisableImagePreviewEvent changeDisableImagePreviewEvent) { - if (mAdapter != null) { - mAdapter.setDisableImagePreview(changeDisableImagePreviewEvent.disableImagePreview); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeOnlyDisablePreviewInVideoAndGifPostsEvent(ChangeOnlyDisablePreviewInVideoAndGifPostsEvent changeOnlyDisablePreviewInVideoAndGifPostsEvent) { - if (mAdapter != null) { - mAdapter.setOnlyDisablePreviewInVideoPosts(changeOnlyDisablePreviewInVideoAndGifPostsEvent.onlyDisablePreviewInVideoAndGifPosts); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeSwipeActionEvent(ChangeSwipeActionEvent changeSwipeActionEvent) { - swipeRightAction = changeSwipeActionEvent.swipeRightAction == -1 ? swipeRightAction : changeSwipeActionEvent.swipeRightAction; - swipeLeftAction = changeSwipeActionEvent.swipeLeftAction == -1 ? swipeLeftAction : changeSwipeActionEvent.swipeLeftAction; - initializeSwipeActionDrawable(); - } - - @Subscribe - public void onNeedForPostListFromPostRecyclerViewAdapterEvent(NeedForPostListFromPostFragmentEvent event) { - if (historyPostFragmentId == event.postFragmentTimeId && mAdapter != null) { - EventBus.getDefault().post(new ProvidePostListToViewPostDetailActivityEvent(historyPostFragmentId, - new ArrayList<>(mAdapter.snapshot()), HistoryPostPagingSource.TYPE_READ_POSTS, null, null, null, - null, null, null, postFilter, null, null)); - } - } - - @Subscribe - public void onChangeHidePostTypeEvent(ChangeHidePostTypeEvent event) { - if (mAdapter != null) { - mAdapter.setHidePostType(event.hidePostType); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeHidePostFlairEvent(ChangeHidePostFlairEvent event) { - if (mAdapter != null) { - mAdapter.setHidePostFlair(event.hidePostFlair); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeHideTheNumberOfAwardsEvent(ChangeHideTheNumberOfAwardsEvent event) { - if (mAdapter != null) { - mAdapter.setHideTheNumberOfAwards(event.hideTheNumberOfAwards); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeHideSubredditAndUserEvent(ChangeHideSubredditAndUserPrefixEvent event) { - if (mAdapter != null) { - mAdapter.setHideSubredditAndUserPrefix(event.hideSubredditAndUserPrefix); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeHideTheNumberOfVotesEvent(ChangeHideTheNumberOfVotesEvent event) { - if (mAdapter != null) { - mAdapter.setHideTheNumberOfVotes(event.hideTheNumberOfVotes); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeHideTheNumberOfCommentsEvent(ChangeHideTheNumberOfCommentsEvent event) { - if (mAdapter != null) { - mAdapter.setHideTheNumberOfComments(event.hideTheNumberOfComments); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeRememberMutingOptionInPostFeedEvent(ChangeRememberMutingOptionInPostFeedEvent event) { - rememberMutingOptionInPostFeed = event.rememberMutingOptionInPostFeedEvent; - if (!event.rememberMutingOptionInPostFeedEvent) { - masterMutingOption = null; - } - } - - @Subscribe - public void onChangeFixedHeightPreviewCardEvent(ChangeFixedHeightPreviewInCardEvent event) { - if (mAdapter != null) { - mAdapter.setFixedHeightPreviewInCard(event.fixedHeightPreviewInCard); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeHideTextPostContentEvent(ChangeHideTextPostContent event) { - if (mAdapter != null) { - mAdapter.setHideTextPostContent(event.hideTextPostContent); - refreshAdapter(); - } - } - - @Subscribe - public void onChangePostFeedMaxResolutionEvent(ChangePostFeedMaxResolutionEvent event) { - if (mAdapter != null) { - mAdapter.setPostFeedMaxResolution(event.postFeedMaxResolution); - refreshAdapter(); - } - } - - @Subscribe - public void onChangeEasierToWatchInFullScreenEvent(ChangeEasierToWatchInFullScreenEvent event) { - if (mAdapter != null) { - mAdapter.setEasierToWatchInFullScreen(event.easierToWatchInFullScreen); - } - } - - 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); - } -} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewCommentsFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewCommentsFragment.java index a8090633..773416d4 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewCommentsFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewCommentsFragment.java @@ -1,100 +1,28 @@ package eu.toldi.infinityforlemmy.fragments; import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import butterknife.BindView; -import butterknife.ButterKnife; +import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.activities.CustomThemePreviewActivity; import eu.toldi.infinityforlemmy.customtheme.CustomTheme; -import eu.toldi.infinityforlemmy.R; +import eu.toldi.infinityforlemmy.databinding.FragmentThemePreviewCommentsBinding; +import eu.toldi.infinityforlemmy.utils.Utils; /** * A simple {@link Fragment} subclass. */ public class ThemePreviewCommentsFragment extends Fragment { - @BindView(R.id.linear_layout_theme_preview_comments_fragment) - LinearLayout linearLayout; - @BindView(R.id.vertical_block_theme_preview_comments_fragment) - View verticalBlock; - @BindView(R.id.author_type_image_view_theme_preview_comments_fragment) - ImageView authorTypeImageView; - @BindView(R.id.author_text_view_theme_preview_comments_fragment) - TextView authorTextView; - @BindView(R.id.author_flair_text_view_theme_preview_comments_fragment) - TextView flairTextView; - @BindView(R.id.comment_time_text_view_theme_preview_comments_fragment) - TextView commentTimeTextView; - @BindView(R.id.comment_markdown_view_theme_preview_comments_fragment) - TextView contentTextView; - @BindView(R.id.up_vote_button_theme_preview_comments_fragment) - ImageView upvoteButton; - @BindView(R.id.score_text_view_theme_preview_comments_fragment) - TextView scoreTextView; - @BindView(R.id.down_vote_button_theme_preview_comments_fragment) - ImageView downvoteButton; - @BindView(R.id.more_button_theme_preview_comments_fragment) - ImageView moreButton; - @BindView(R.id.expand_button_theme_preview_comments_fragment) - ImageView expandButton; - @BindView(R.id.save_button_theme_preview_comments_fragment) - ImageView saveButton; - @BindView(R.id.reply_button_theme_preview_comments_fragment) - ImageView replyButton; - @BindView(R.id.divider_theme_preview_comments_fragment) - View divider; - - @BindView(R.id.linear_layout_award_background_theme_preview_comments_fragment) - LinearLayout linearLayoutAwardBackground; - @BindView(R.id.vertical_block_award_background_theme_preview_comments_fragment) - View verticalBlockAwardBackground; - @BindView(R.id.author_type_image_view_award_background_theme_preview_comments_fragment) - ImageView authorTypeImageViewAwardBackground; - @BindView(R.id.author_text_view_award_background_theme_preview_comments_fragment) - TextView authorTextViewAwardBackground; - @BindView(R.id.author_flair_text_view_award_background_theme_preview_comments_fragment) - TextView flairTextViewAwardBackground; - @BindView(R.id.comment_time_text_view_award_background_theme_preview_comments_fragment) - TextView commentTimeTextViewAwardBackground; - @BindView(R.id.comment_markdown_view_award_background_theme_preview_comments_fragment) - TextView contentTextViewAwardBackground; - @BindView(R.id.up_vote_button_award_background_theme_preview_comments_fragment) - ImageView upvoteButtonAwardBackground; - @BindView(R.id.score_text_view_award_background_theme_preview_comments_fragment) - TextView scoreTextViewAwardBackground; - @BindView(R.id.down_vote_button_award_background_theme_preview_comments_fragment) - ImageView downvoteButtonAwardBackground; - @BindView(R.id.more_button_award_background_theme_preview_comments_fragment) - ImageView moreButtonAwardBackground; - @BindView(R.id.expand_button_award_background_theme_preview_comments_fragment) - ImageView expandButtonAwardBackground; - @BindView(R.id.save_button_award_background_theme_preview_comments_fragment) - ImageView saveButtonAwardBackground; - @BindView(R.id.reply_button_award_background_theme_preview_comments_fragment) - ImageView replyButtonAwardBackground; - @BindView(R.id.divider_award_background_theme_preview_comments_fragment) - View dividerAwardBackground; - - @BindView(R.id.linear_layout_fully_collapsed_theme_preview_comments_fragment) - LinearLayout linearLayoutFullyCollapsed; - @BindView(R.id.vertical_block_fully_collapsed_theme_preview_comments_fragment) - View verticalBlockFullyCollapsed; - @BindView(R.id.author_text_view_fully_collapsed_theme_preview_comments_fragment) - TextView authorTextViewFullyCollapsed; - @BindView(R.id.score_text_view_fully_collapsed_theme_preview_comments_fragment) - TextView scoreTextViewFullyCollapsed; - @BindView(R.id.time_text_view_fully_collapsed_theme_preview_comments_fragment) - TextView timeTextViewFullyCollapsed; + private FragmentThemePreviewCommentsBinding binding; private CustomThemePreviewActivity activity; public ThemePreviewCommentsFragment() { @@ -103,65 +31,69 @@ public class ThemePreviewCommentsFragment extends Fragment { @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_theme_preview_comments, container, false); - ButterKnife.bind(this, rootView); + binding = FragmentThemePreviewCommentsBinding.inflate(inflater, container, false); CustomTheme customTheme = activity.getCustomTheme(); - linearLayout.setBackgroundColor(customTheme.commentBackgroundColor); - authorTypeImageView.setColorFilter(customTheme.moderator, android.graphics.PorterDuff.Mode.SRC_IN); - authorTextView.setTextColor(customTheme.moderator); - commentTimeTextView.setTextColor(customTheme.secondaryTextColor); - contentTextView.setTextColor(customTheme.commentColor); - flairTextView.setTextColor(customTheme.authorFlairTextColor); - divider.setBackgroundColor(customTheme.dividerColor); - upvoteButton.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(customTheme.commentIconAndInfoColor); - downvoteButton.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - moreButton.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - expandButton.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - saveButton.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - replyButton.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - linearLayoutAwardBackground.setBackgroundColor(customTheme.awardedCommentBackgroundColor); - authorTypeImageViewAwardBackground.setColorFilter(customTheme.moderator, android.graphics.PorterDuff.Mode.SRC_IN); - authorTextViewAwardBackground.setTextColor(customTheme.moderator); - commentTimeTextViewAwardBackground.setTextColor(customTheme.secondaryTextColor); - contentTextViewAwardBackground.setTextColor(customTheme.commentColor); - flairTextViewAwardBackground.setTextColor(customTheme.authorFlairTextColor); - dividerAwardBackground.setBackgroundColor(customTheme.dividerColor); - upvoteButtonAwardBackground.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextViewAwardBackground.setTextColor(customTheme.commentIconAndInfoColor); - downvoteButtonAwardBackground.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - moreButtonAwardBackground.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - expandButtonAwardBackground.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - saveButtonAwardBackground.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - replyButtonAwardBackground.setColorFilter(customTheme.commentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + Drawable expandDrawable = Utils.getTintedDrawable(activity, R.drawable.ic_expand_more_grey_24dp, customTheme.commentIconAndInfoColor); - linearLayoutFullyCollapsed.setBackgroundColor(customTheme.fullyCollapsedCommentBackgroundColor); - authorTextViewFullyCollapsed.setTextColor(customTheme.username); - scoreTextViewFullyCollapsed.setTextColor(customTheme.secondaryTextColor); - timeTextViewFullyCollapsed.setTextColor(customTheme.secondaryTextColor); + binding.linearLayoutThemePreviewCommentsFragment.setBackgroundColor(customTheme.commentBackgroundColor); + binding.authorTypeImageViewThemePreviewCommentsFragment.setColorFilter(customTheme.moderator, android.graphics.PorterDuff.Mode.SRC_IN); + binding.authorTextViewThemePreviewCommentsFragment.setTextColor(customTheme.moderator); + binding.commentTimeTextViewThemePreviewCommentsFragment.setTextColor(customTheme.secondaryTextColor); + binding.commentMarkdownViewThemePreviewCommentsFragment.setTextColor(customTheme.commentColor); + binding.authorFlairTextViewThemePreviewCommentsFragment.setTextColor(customTheme.authorFlairTextColor); + binding.dividerThemePreviewCommentsFragment.setBackgroundColor(customTheme.dividerColor); + binding.upvoteButtonThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.upvoteButtonThemePreviewCommentsFragment.setTextColor(customTheme.commentIconAndInfoColor); + binding.downvoteButtonThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.moreButtonThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.expandButtonThemePreviewCommentsFragment.setCompoundDrawablesWithIntrinsicBounds(expandDrawable, null, null, null); + binding.saveButtonThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.replyButtonThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + + binding.linearLayoutAwardBackgroundThemePreviewCommentsFragment.setBackgroundColor(customTheme.awardedCommentBackgroundColor); + binding.authorTypeImageViewAwardBackgroundThemePreviewCommentsFragment.setColorFilter(customTheme.moderator, android.graphics.PorterDuff.Mode.SRC_IN); + binding.authorTextViewAwardBackgroundThemePreviewCommentsFragment.setTextColor(customTheme.moderator); + binding.commentTimeTextViewAwardBackgroundThemePreviewCommentsFragment.setTextColor(customTheme.secondaryTextColor); + binding.commentMarkdownViewAwardBackgroundThemePreviewCommentsFragment.setTextColor(customTheme.commentColor); + binding.authorFlairTextViewAwardBackgroundThemePreviewCommentsFragment.setTextColor(customTheme.authorFlairTextColor); + binding.dividerAwardBackgroundThemePreviewCommentsFragment.setBackgroundColor(customTheme.dividerColor); + binding.upvoteButtonAwardBackgroundThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.upvoteButtonAwardBackgroundThemePreviewCommentsFragment.setTextColor(customTheme.commentIconAndInfoColor); + binding.downvoteButtonAwardBackgroundThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.moreButtonAwardBackgroundThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.expandButtonAwardBackgroundThemePreviewCommentsFragment.setCompoundDrawablesWithIntrinsicBounds(expandDrawable, null, null, null); + binding.saveButtonAwardBackgroundThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + binding.replyButtonAwardBackgroundThemePreviewCommentsFragment.setIconTint(ColorStateList.valueOf(customTheme.commentIconAndInfoColor)); + + binding.linearLayoutFullyCollapsedThemePreviewCommentsFragment.setBackgroundColor(customTheme.fullyCollapsedCommentBackgroundColor); + binding.authorTextViewFullyCollapsedThemePreviewCommentsFragment.setTextColor(customTheme.username); + binding.scoreTextViewFullyCollapsedThemePreviewCommentsFragment.setTextColor(customTheme.secondaryTextColor); + binding.timeTextViewFullyCollapsedThemePreviewCommentsFragment.setTextColor(customTheme.secondaryTextColor); if (activity.typeface != null) { - authorTextView.setTypeface(activity.typeface); - commentTimeTextView.setTypeface(activity.typeface); - flairTextView.setTypeface(activity.typeface); - scoreTextView.setTypeface(activity.typeface); - authorTextViewAwardBackground.setTypeface(activity.typeface); - commentTimeTextViewAwardBackground.setTypeface(activity.typeface); - flairTextViewAwardBackground.setTypeface(activity.typeface); - scoreTextViewAwardBackground.setTypeface(activity.typeface); - authorTextViewFullyCollapsed.setTypeface(activity.typeface); - scoreTextViewFullyCollapsed.setTypeface(activity.typeface); - timeTextViewFullyCollapsed.setTypeface(activity.typeface); + binding.authorTextViewThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.commentTimeTextViewThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.authorFlairTextViewThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.upvoteButtonThemePreviewCommentsFragment.setTypeface(activity.typeface); + + binding.authorTextViewAwardBackgroundThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.commentTimeTextViewAwardBackgroundThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.authorFlairTextViewAwardBackgroundThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.upvoteButtonAwardBackgroundThemePreviewCommentsFragment.setTypeface(activity.typeface); + + binding.authorTextViewFullyCollapsedThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.scoreTextViewFullyCollapsedThemePreviewCommentsFragment.setTypeface(activity.typeface); + binding.timeTextViewFullyCollapsedThemePreviewCommentsFragment.setTypeface(activity.typeface); } if (activity.contentTypeface != null) { - contentTextView.setTypeface(activity.contentTypeface); - contentTextViewAwardBackground.setTypeface(activity.contentTypeface); + binding.commentMarkdownViewThemePreviewCommentsFragment.setTypeface(activity.contentTypeface); + binding.commentMarkdownViewAwardBackgroundThemePreviewCommentsFragment.setTypeface(activity.contentTypeface); } - return rootView; + return binding.getRoot(); } @Override diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewPostsFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewPostsFragment.java index 0e075d85..79b43a9b 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewPostsFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ThemePreviewPostsFragment.java @@ -8,82 +8,26 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.content.res.AppCompatResources; -import androidx.cardview.widget.CardView; import androidx.fragment.app.Fragment; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; -import com.libRG.CustomTextView; -import butterknife.BindView; -import butterknife.ButterKnife; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.activities.CustomThemePreviewActivity; import eu.toldi.infinityforlemmy.customtheme.CustomTheme; -import eu.toldi.infinityforlemmy.customviews.AspectRatioGifImageView; +import eu.toldi.infinityforlemmy.databinding.FragmentThemePreviewPostsBinding; /** * A simple {@link Fragment} subclass. */ public class ThemePreviewPostsFragment extends Fragment { - @BindView(R.id.card_view_theme_preview_posts_fragment) - CardView cardView; - @BindView(R.id.icon_gif_image_view_theme_preview_posts_fragment) - AspectRatioGifImageView iconImageView; - @BindView(R.id.subreddit_name_text_view_theme_preview_posts_fragment) - TextView subredditNameTextView; - @BindView(R.id.user_text_view_theme_preview_posts_fragment) - TextView usernameTextView; - @BindView(R.id.stickied_post_image_view_theme_preview_posts_fragment) - ImageView stickiedPostImageView; - @BindView(R.id.post_time_text_view_best_theme_preview_posts_fragment) - TextView postTimeTextView; - @BindView(R.id.title_text_view_best_theme_preview_posts_fragment) - TextView titleTextView; - @BindView(R.id.content_text_view_theme_preview_posts_fragment) - TextView contentTextView; - @BindView(R.id.type_text_view_theme_preview_posts_fragment) - CustomTextView typeTextView; - @BindView(R.id.spoiler_custom_text_view_theme_preview_posts_fragment) - CustomTextView spoilerTextView; - @BindView(R.id.nsfw_text_view_theme_preview_posts_fragment) - CustomTextView nsfwTextView; - @BindView(R.id.flair_custom_text_view_theme_preview_posts_fragment) - CustomTextView flairTextView; - @BindView(R.id.awards_text_view_theme_preview_posts_fragment) - CustomTextView awardsTextView; - @BindView(R.id.archived_image_view_theme_preview_posts_fragment) - ImageView archivedImageView; - @BindView(R.id.locked_image_view_theme_preview_posts_fragment) - ImageView lockedImageView; - @BindView(R.id.crosspost_image_view_theme_preview_posts_fragment) - ImageView crosspostImageView; - @BindView(R.id.link_text_view_theme_preview_posts_fragment) - TextView linkTextView; - @BindView(R.id.progress_bar_theme_preview_posts_fragment) - ProgressBar progressBar; - @BindView(R.id.image_view_no_preview_link_theme_preview_posts_fragment) - ImageView noPreviewLinkImageView; - @BindView(R.id.plus_button_theme_preview_posts_fragment) - ImageView upvoteButton; - @BindView(R.id.score_text_view_theme_preview_posts_fragment) - TextView scoreTextView; - @BindView(R.id.minus_button_theme_preview_posts_fragment) - ImageView downvoteButton; - @BindView(R.id.comments_count_theme_preview_posts_fragment) - TextView commentsCountTextView; - @BindView(R.id.save_button_theme_preview_posts_fragment) - ImageView saveButton; - @BindView(R.id.share_button_theme_preview_posts_fragment) - ImageView shareButton; + private FragmentThemePreviewPostsBinding binding; private CustomThemePreviewActivity activity; public ThemePreviewPostsFragment() { @@ -94,74 +38,74 @@ public class ThemePreviewPostsFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_theme_preview_posts, container, false); - ButterKnife.bind(this, rootView); + binding = FragmentThemePreviewPostsBinding.inflate(inflater, container, false); CustomTheme customTheme = activity.getCustomTheme(); - cardView.setBackgroundTintList(ColorStateList.valueOf(customTheme.cardViewBackgroundColor)); + binding.cardViewThemePreviewPostsFragment.setBackgroundTintList(ColorStateList.valueOf(customTheme.cardViewBackgroundColor)); Glide.with(this).load(R.drawable.subreddit_default_icon) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconImageView); - subredditNameTextView.setTextColor(customTheme.subreddit); - usernameTextView.setTextColor(customTheme.username); - postTimeTextView.setTextColor(customTheme.secondaryTextColor); - titleTextView.setTextColor(customTheme.postTitleColor); - contentTextView.setTextColor(customTheme.postContentColor); - stickiedPostImageView.setColorFilter(customTheme.stickiedPostIconTint, PorterDuff.Mode.SRC_IN); - typeTextView.setBackgroundColor(customTheme.postTypeBackgroundColor); - typeTextView.setBorderColor(customTheme.postTypeBackgroundColor); - typeTextView.setTextColor(customTheme.postTypeTextColor); - spoilerTextView.setBackgroundColor(customTheme.spoilerBackgroundColor); - spoilerTextView.setBorderColor(customTheme.spoilerBackgroundColor); - spoilerTextView.setTextColor(customTheme.spoilerTextColor); - nsfwTextView.setBackgroundColor(customTheme.nsfwBackgroundColor); - nsfwTextView.setBorderColor(customTheme.nsfwBackgroundColor); - nsfwTextView.setTextColor(customTheme.nsfwTextColor); - flairTextView.setBackgroundColor(customTheme.flairBackgroundColor); - flairTextView.setBorderColor(customTheme.flairBackgroundColor); - flairTextView.setTextColor(customTheme.flairTextColor); - awardsTextView.setBackgroundColor(customTheme.awardsBackgroundColor); - awardsTextView.setBorderColor(customTheme.awardsBackgroundColor); - awardsTextView.setTextColor(customTheme.awardsTextColor); - archivedImageView.setColorFilter(customTheme.archivedTint, PorterDuff.Mode.SRC_IN); - lockedImageView.setColorFilter(customTheme.lockedIconTint, PorterDuff.Mode.SRC_IN); - crosspostImageView.setColorFilter(customTheme.crosspostIconTint, PorterDuff.Mode.SRC_IN); - linkTextView.setTextColor(customTheme.secondaryTextColor); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(customTheme.colorAccent)); - noPreviewLinkImageView.setBackgroundColor(customTheme.noPreviewPostTypeBackgroundColor); - upvoteButton.setColorFilter(customTheme.postIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(customTheme.postIconAndInfoColor); - downvoteButton.setColorFilter(customTheme.postIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - commentsCountTextView.setTextColor(customTheme.postIconAndInfoColor); + .into(binding.iconGifImageViewThemePreviewPostsFragment); + binding.subredditNameTextViewThemePreviewPostsFragment.setTextColor(customTheme.subreddit); + binding.userTextViewThemePreviewPostsFragment.setTextColor(customTheme.username); + binding.postTimeTextViewBestThemePreviewPostsFragment.setTextColor(customTheme.secondaryTextColor); + binding.titleTextViewBestThemePreviewPostsFragment.setTextColor(customTheme.postTitleColor); + binding.contentTextViewThemePreviewPostsFragment.setTextColor(customTheme.postContentColor); + binding.stickiedPostImageViewThemePreviewPostsFragment.setColorFilter(customTheme.stickiedPostIconTint, PorterDuff.Mode.SRC_IN); + binding.typeTextViewThemePreviewPostsFragment.setBackgroundColor(customTheme.postTypeBackgroundColor); + binding.typeTextViewThemePreviewPostsFragment.setBorderColor(customTheme.postTypeBackgroundColor); + binding.typeTextViewThemePreviewPostsFragment.setTextColor(customTheme.postTypeTextColor); + binding.spoilerCustomTextViewThemePreviewPostsFragment.setBackgroundColor(customTheme.spoilerBackgroundColor); + binding.spoilerCustomTextViewThemePreviewPostsFragment.setBorderColor(customTheme.spoilerBackgroundColor); + binding.spoilerCustomTextViewThemePreviewPostsFragment.setTextColor(customTheme.spoilerTextColor); + binding.nsfwTextViewThemePreviewPostsFragment.setBackgroundColor(customTheme.nsfwBackgroundColor); + binding.nsfwTextViewThemePreviewPostsFragment.setBorderColor(customTheme.nsfwBackgroundColor); + binding.nsfwTextViewThemePreviewPostsFragment.setTextColor(customTheme.nsfwTextColor); + binding.flairCustomTextViewThemePreviewPostsFragment.setBackgroundColor(customTheme.flairBackgroundColor); + binding.flairCustomTextViewThemePreviewPostsFragment.setBorderColor(customTheme.flairBackgroundColor); + binding.flairCustomTextViewThemePreviewPostsFragment.setTextColor(customTheme.flairTextColor); + binding.awardsTextViewThemePreviewPostsFragment.setBackgroundColor(customTheme.awardsBackgroundColor); + binding.awardsTextViewThemePreviewPostsFragment.setBorderColor(customTheme.awardsBackgroundColor); + binding.awardsTextViewThemePreviewPostsFragment.setTextColor(customTheme.awardsTextColor); + binding.archivedImageViewThemePreviewPostsFragment.setColorFilter(customTheme.archivedTint, PorterDuff.Mode.SRC_IN); + binding.lockedImageViewThemePreviewPostsFragment.setColorFilter(customTheme.lockedIconTint, PorterDuff.Mode.SRC_IN); + binding.crosspostImageViewThemePreviewPostsFragment.setColorFilter(customTheme.crosspostIconTint, PorterDuff.Mode.SRC_IN); + binding.linkTextViewThemePreviewPostsFragment.setTextColor(customTheme.secondaryTextColor); + binding.progressBarThemePreviewPostsFragment.setIndeterminateTintList(ColorStateList.valueOf(customTheme.colorAccent)); + binding.imageViewNoPreviewLinkThemePreviewPostsFragment.setBackgroundColor(customTheme.noPreviewPostTypeBackgroundColor); + binding.upvoteButtonThemePreviewPostsFragment.setIconTint(ColorStateList.valueOf(customTheme.postIconAndInfoColor)); + binding.upvoteButtonThemePreviewPostsFragment.setTextColor(customTheme.postIconAndInfoColor); + binding.downvoteButtonThemePreviewPostsFragment.setIconTint(ColorStateList.valueOf(customTheme.postIconAndInfoColor)); + binding.commentsCountButtonThemePreviewPostsFragment.setTextColor(customTheme.postIconAndInfoColor); Drawable commentIcon = AppCompatResources.getDrawable(activity, R.drawable.ic_comment_grey_24dp); if (commentIcon != null) { commentIcon.setTint(customTheme.postIconAndInfoColor); } - commentsCountTextView.setCompoundDrawablesWithIntrinsicBounds(commentIcon, null, null, null); - saveButton.setColorFilter(customTheme.postIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - shareButton.setColorFilter(customTheme.postIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + binding.commentsCountButtonThemePreviewPostsFragment.setCompoundDrawablesWithIntrinsicBounds(commentIcon, null, null, null); + binding.saveButtonThemePreviewPostsFragment.setIconTint(ColorStateList.valueOf(customTheme.postIconAndInfoColor)); + binding.shareButtonThemePreviewPostsFragment.setIconTint(ColorStateList.valueOf(customTheme.postIconAndInfoColor)); if (activity.typeface != null) { - subredditNameTextView.setTypeface(activity.typeface); - usernameTextView.setTypeface(activity.typeface); - postTimeTextView.setTypeface(activity.typeface); - typeTextView.setTypeface(activity.typeface); - spoilerTextView.setTypeface(activity.typeface); - nsfwTextView.setTypeface(activity.typeface); - flairTextView.setTypeface(activity.typeface); - awardsTextView.setTypeface(activity.typeface); - linkTextView.setTypeface(activity.typeface); - scoreTextView.setTypeface(activity.typeface); - commentsCountTextView.setTypeface(activity.typeface); + binding.subredditNameTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.userTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.postTimeTextViewBestThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.typeTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.spoilerCustomTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.nsfwTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.flairCustomTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.awardsTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.linkTextViewThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.upvoteButtonThemePreviewPostsFragment.setTypeface(activity.typeface); + binding.commentsCountButtonThemePreviewPostsFragment.setTypeface(activity.typeface); } if (activity.titleTypeface != null) { - titleTextView.setTypeface(activity.titleTypeface); + binding.titleTextViewBestThemePreviewPostsFragment.setTypeface(activity.titleTypeface); } if (activity.contentTypeface != null) { - contentTextView.setTypeface(activity.contentTypeface); + binding.contentTextViewThemePreviewPostsFragment.setTypeface(activity.contentTypeface); } - return rootView; + + return binding.getRoot(); } @Override diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewImgurVideoFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewImgurVideoFragment.java index a2fc8a51..3906448a 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewImgurVideoFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewImgurVideoFragment.java @@ -15,8 +15,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -39,6 +37,7 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSource; import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.button.MaterialButton; import com.google.common.collect.ImmutableList; import javax.inject.Inject; @@ -68,13 +67,17 @@ public class ViewImgurVideoFragment extends Fragment { @BindView(R.id.player_view_view_imgur_video_fragment) PlayerView videoPlayerView; @BindView(R.id.mute_exo_playback_control_view) - ImageButton muteButton; + MaterialButton muteButton; @BindView(R.id.bottom_navigation_exo_playback_control_view) BottomAppBar bottomAppBar; @BindView(R.id.title_text_view_exo_playback_control_view) TextView titleTextView; + @BindView(R.id.back_button_exo_playback_control_view) + MaterialButton backButton; @BindView(R.id.download_image_view_exo_playback_control_view) - ImageView downloadImageView; + MaterialButton downloadButton; + @BindView(R.id.playback_speed_image_view_exo_playback_control_view) + MaterialButton playbackSpeedButton; private ViewImgurMediaActivity activity; private ImgurMedia imgurMedia; private ExoPlayer player; @@ -105,6 +108,10 @@ public class ViewImgurVideoFragment extends Fragment { setHasOptionsMenu(true); + if (activity.typeface != null) { + titleTextView.setTypeface(activity.typeface); + } + activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); imgurMedia = getArguments().getParcelable(EXTRA_IMGUR_VIDEO); @@ -158,22 +165,40 @@ public class ViewImgurVideoFragment extends Fragment { setPlaybackSpeed(Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.DEFAULT_PLAYBACK_SPEED, "100"))); preparePlayer(savedInstanceState); + titleTextView.setText(getString(R.string.view_imgur_media_activity_video_label, + getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); + if (activity.isUseBottomAppBar()) { bottomAppBar.setVisibility(View.VISIBLE); - titleTextView.setText(getString(R.string.view_imgur_media_activity_video_label, - getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); - downloadImageView.setOnClickListener(view -> { + + backButton.setOnClickListener(view -> { + activity.finish(); + }); + + downloadButton.setOnClickListener(view -> { if (isDownloading) { return; } isDownloading = true; requestPermissionAndDownload(); }); + + playbackSpeedButton.setOnClickListener(view -> { + changePlaybackSpeed(); + }); } return rootView; } + private void changePlaybackSpeed() { + PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); + playbackSpeedBottomSheetFragment.setArguments(bundle); + playbackSpeedBottomSheetFragment.show(getChildFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); + } + @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.view_imgur_video_fragment, menu); @@ -191,11 +216,7 @@ public class ViewImgurVideoFragment extends Fragment { requestPermissionAndDownload(); return true; } else if (item.getItemId() == R.id.action_playback_speed_view_imgur_video_fragment) { - PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); - playbackSpeedBottomSheetFragment.setArguments(bundle); - playbackSpeedBottomSheetFragment.show(getChildFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); + changePlaybackSpeed(); return true; } return false; @@ -266,17 +287,17 @@ public class ViewImgurVideoFragment extends Fragment { isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); if (isMute) { player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); + muteButton.setIconResource(R.drawable.ic_mute_24dp); } else { player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); + muteButton.setIconResource(R.drawable.ic_unmute_24dp); } } else if (muteVideo) { isMute = true; player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); + muteButton.setIconResource(R.drawable.ic_mute_24dp); } else { - muteButton.setImageResource(R.drawable.ic_unmute_24dp); + muteButton.setIconResource(R.drawable.ic_unmute_24dp); } player.addListener(new Player.Listener() { @@ -292,11 +313,11 @@ public class ViewImgurVideoFragment extends Fragment { if (isMute) { isMute = false; player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); + muteButton.setIconResource(R.drawable.ic_unmute_24dp); } else { isMute = true; player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); + muteButton.setIconResource(R.drawable.ic_mute_24dp); } }); break; diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java index 2cd9126e..29e92a93 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java @@ -17,6 +17,7 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.Menu; @@ -94,6 +95,9 @@ import eu.toldi.infinityforlemmy.comment.Comment; import eu.toldi.infinityforlemmy.comment.FetchComment; import eu.toldi.infinityforlemmy.comment.FetchRemovedComment; import eu.toldi.infinityforlemmy.comment.FetchRemovedCommentReveddit; +import eu.toldi.infinityforlemmy.comment.ParseComment; +import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; +import eu.toldi.infinityforlemmy.commentfilter.FetchCommentFilter; import eu.toldi.infinityforlemmy.community.BlockCommunity; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.customviews.CustomToroContainer; @@ -232,6 +236,10 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic boolean mRespectSubredditRecommendedSortType; @State long viewPostDetailFragmentId; + @State + boolean commentFilterFetched; + @State + CommentFilter mCommentFilter; @State boolean isCommunityBlocked; @@ -292,7 +300,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic applyTheme(); - mRecyclerView.addOnWindowFocusChangedListener(this::onWindowFocusChanged); + mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); @@ -459,7 +467,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { - if (!(viewHolder instanceof CommentsRecyclerViewAdapter.CommentViewHolder)) { + if (!(viewHolder instanceof CommentsRecyclerViewAdapter.CommentBaseViewHolder)) { return makeMovementFlags(0, 0); } int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; @@ -554,7 +562,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic touchHelper.attachToRecyclerView((mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView)); } - mSwipeRefreshLayout.setOnRefreshListener(() -> refresh(true, true)); + mSwipeRefreshLayout.setOnRefreshListener(() -> refresh()); mSmoothScroller = new LinearSmoothScroller(activity) { @Override @@ -644,7 +652,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic public SortType.Type getSortType() { return sortType; } - } ); + }); if (mCommentsRecyclerView != null) { mRecyclerView.setAdapter(mPostAdapter); mCommentsRecyclerView.setAdapter(mCommentsAdapter); @@ -653,21 +661,15 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic mRecyclerView.setAdapter(mConcatAdapter); } - if (comments == null) { - fetchCommentsRespectRecommendedSort(false); + if (commentFilterFetched) { + fetchCommentsAfterCommentFilterAvailable(); } else { - if (isRefreshing) { - isRefreshing = false; - refresh(true, true); - } else if (isFetchingComments) { - fetchCommentsRespectRecommendedSort(false); - } else { - mCommentsAdapter.addComments(comments, hasMoreChildren); - if (isLoadingMoreChildren) { - isLoadingMoreChildren = false; - fetchMoreComments(); - } - } + FetchCommentFilter.fetchCommentFilter(mExecutor, new Handler(Looper.getMainLooper()), mRedditDataRoomDatabase, mPost.getSubredditName(), + commentFilter -> { + mCommentFilter = commentFilter; + commentFilterFetched = true; + fetchCommentsAfterCommentFilterAvailable(); + }); } } @@ -678,6 +680,25 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic }); } + public void fetchCommentsAfterCommentFilterAvailable() { + if (comments == null) { + fetchCommentsRespectRecommendedSort(false); + } else { + if (isRefreshing) { + isRefreshing = false; + refresh(true, true); + } else if (isFetchingComments) { + fetchCommentsRespectRecommendedSort(false); + } else { + mCommentsAdapter.addComments(comments, hasMoreChildren); + if (isLoadingMoreChildren) { + isLoadingMoreChildren = false; + fetchMoreComments(); + } + } + } + } + private void setupMenu() { if (mMenu != null) { MenuItem saveItem = mMenu.findItem(R.id.action_save_view_post_detail_fragment); @@ -1348,7 +1369,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic mPostDetailsSharedPreferences, mExoCreator, post1 -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition))); mSwipeRefreshLayout.setRefreshing(false); - FetchComment.fetchComments(mExecutor, new Handler(), mRetrofit.getRetrofit(), mAccessToken, post.getId(), mSingleCommentId == null || mSingleCommentId == 0 ? null : mSingleCommentParentId == 0 ? mSingleCommentId : mSingleCommentParentId, sortType, mExpandChildren, 1, new FetchComment.FetchCommentListener() { + FetchComment.fetchComments(mExecutor, new Handler(), mRetrofit.getRetrofit(), mAccessToken, post.getId(), mSingleCommentId == null || mSingleCommentId == 0 ? null : mSingleCommentParentId == 0 ? mSingleCommentId : mSingleCommentParentId, sortType, mExpandChildren, 1, mCommentFilter, new FetchComment.FetchCommentListener() { @Override public void onFetchCommentSuccess(ArrayList expandedComments, Integer parentId, ArrayList children) { pages_loaded++; @@ -1387,13 +1408,9 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic fetchCommentsRespectRecommendedSort(false); } ViewPostDetailFragment.this.children = children; - - hasMoreChildren = false; - mCommentsAdapter.addComments(expandedComments, hasMoreChildren); - - } + @Override public void onFetchCommentFailed() { if (isAdded()) { @@ -1468,7 +1485,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic FetchComment.fetchComments(mExecutor, new Handler(), mRetrofit.getRetrofit(), mAccessToken, mPost.getId(), mSingleCommentId == null || mSingleCommentId == 0 ? null : mSingleCommentParentId == 0 ? mSingleCommentId : mSingleCommentParentId, sortType, mExpandChildren, pages_loaded + 1, - new FetchComment.FetchCommentListener() { + mCommentFilter, new FetchComment.FetchCommentListener() { @Override public void onFetchCommentSuccess(ArrayList expandedComments, Integer parentId, ArrayList children) { @@ -1557,7 +1574,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic isLoadingMoreChildren = true; FetchComment.fetchComments(mExecutor, new Handler(), mRetrofit.getRetrofit(), mAccessToken, - mPost.getId(), (mSingleCommentId == null || mSingleCommentId == 0) ? null : (mSingleCommentParentId == null || mSingleCommentParentId == 0 ? mSingleCommentId : mSingleCommentParentId), sortType, mExpandChildren, pages_loaded + 1, new FetchComment.FetchCommentListener() { + mPost.getId(), (mSingleCommentId == null || mSingleCommentId == 0) ? null : (mSingleCommentParentId == null || mSingleCommentParentId == 0 ? mSingleCommentId : mSingleCommentParentId), sortType, mExpandChildren, pages_loaded + 1, mCommentFilter, new FetchComment.FetchCommentListener() { @Override public void onFetchCommentSuccess(ArrayList expandedComments, Integer parentId, ArrayList children) { pages_loaded++; diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewRedditGalleryVideoFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewRedditGalleryVideoFragment.java index 25f94f62..1b56ff37 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewRedditGalleryVideoFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewRedditGalleryVideoFragment.java @@ -16,7 +16,6 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -39,6 +38,7 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSource; import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.button.MaterialButton; import com.google.common.collect.ImmutableList; import javax.inject.Inject; @@ -75,8 +75,12 @@ public class ViewRedditGalleryVideoFragment extends Fragment { BottomAppBar bottomAppBar; @BindView(R.id.title_text_view_exo_playback_control_view) TextView titleTextView; + @BindView(R.id.back_button_exo_playback_control_view) + MaterialButton backButton; @BindView(R.id.download_image_view_exo_playback_control_view) - ImageView downloadImageView; + MaterialButton downloadButton; + @BindView(R.id.playback_speed_image_view_exo_playback_control_view) + MaterialButton playbackSpeedButton; private ViewRedditGalleryActivity activity; private Post.Gallery galleryVideo; private String subredditName; @@ -168,22 +172,37 @@ public class ViewRedditGalleryVideoFragment extends Fragment { Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.DEFAULT_PLAYBACK_SPEED, "100")); preparePlayer(savedInstanceState); + titleTextView.setText(getString(R.string.view_reddit_gallery_activity_video_label, + getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); + if (activity.isUseBottomAppBar()) { bottomAppBar.setVisibility(View.VISIBLE); - titleTextView.setText(getString(R.string.view_reddit_gallery_activity_video_label, - getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); - downloadImageView.setOnClickListener(view -> { + backButton.setOnClickListener(view -> { + activity.finish(); + }); + downloadButton.setOnClickListener(view -> { if (isDownloading) { return; } isDownloading = true; requestPermissionAndDownload(); }); + playbackSpeedButton.setOnClickListener(view -> { + changePlaybackSpeed(); + }); } return rootView; } + private void changePlaybackSpeed() { + PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); + playbackSpeedBottomSheetFragment.setArguments(bundle); + playbackSpeedBottomSheetFragment.show(getChildFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); + } + @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.view_reddit_gallery_video_fragment, menu); @@ -201,11 +220,7 @@ public class ViewRedditGalleryVideoFragment extends Fragment { requestPermissionAndDownload(); return true; } else if (item.getItemId() == R.id.action_playback_speed_view_reddit_gallery_video_fragment) { - PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); - playbackSpeedBottomSheetFragment.setArguments(bundle); - playbackSpeedBottomSheetFragment.show(getChildFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); + return true; } return false; diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java index 9f010ccd..5e6f1bb7 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java @@ -32,8 +32,7 @@ public class MessageViewModel extends ViewModel { hasMessageLiveData = Transformations.switchMap(messageDataSourceFactory.getMessageDataSourceLiveData(), MessageDataSource::hasPostLiveData); - whereLiveData = new MutableLiveData<>(); - whereLiveData.postValue(where); + whereLiveData = new MutableLiveData<>(where); PagedList.Config pagedListConfig = (new PagedList.Config.Builder()) diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/multireddit/MultiRedditViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/multireddit/MultiRedditViewModel.java index ab2aac01..9541d1d6 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/multireddit/MultiRedditViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/multireddit/MultiRedditViewModel.java @@ -23,8 +23,7 @@ public class MultiRedditViewModel extends AndroidViewModel { public MultiRedditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { super(application); mMultiRedditRepository = new MultiRedditRepository(redditDataRoomDatabase, accountName); - searchQueryLiveData = new MutableLiveData<>(); - searchQueryLiveData.postValue(""); + searchQueryLiveData = new MutableLiveData<>(""); mAllMultiReddits = Transformations.switchMap(searchQueryLiveData, searchQuery -> mMultiRedditRepository.getAllMultiRedditsWithSearchQuery(searchQuery)); mAllFavoriteMultiReddits = Transformations.switchMap(searchQueryLiveData, searchQuery -> mMultiRedditRepository.getAllFavoriteMultiRedditsWithSearchQuery(searchQuery)); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java index 96188fb8..75ff3a56 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java @@ -49,10 +49,9 @@ public class HistoryPostViewModel extends ViewModel { this.postFilter = postFilter; this.postEnricher = postEnricher; - postFilterLiveData = new MutableLiveData<>(); - postFilterLiveData.postValue(postFilter); + postFilterLiveData = new MutableLiveData<>(postFilter); - Pager pager = new Pager<>(new PagingConfig(25, 25, false), this::returnPagingSource); + Pager pager = new Pager<>(new PagingConfig(25, 4, false, 10), this::returnPagingSource); posts = Transformations.switchMap(postFilterLiveData, postFilterValue -> PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), ViewModelKt.getViewModelScope(this))); } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java index cf8106fa..b692c0f4 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java @@ -69,10 +69,8 @@ public class PostViewModel extends ViewModel { this.name = option; this.postEnricher = postEnricher; - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - postFilterLiveData = new MutableLiveData<>(); - postFilterLiveData.postValue(postFilter); + sortTypeLiveData = new MutableLiveData<>(sortType); + postFilterLiveData = new MutableLiveData<>(postFilter); sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData); @@ -112,10 +110,8 @@ public class PostViewModel extends ViewModel { this.name = subredditName; this.postEnricher = postEnricher; - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - postFilterLiveData = new MutableLiveData<>(); - postFilterLiveData.postValue(postFilter); + sortTypeLiveData = new MutableLiveData<>(sortType); + postFilterLiveData = new MutableLiveData<>(postFilter); sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData); @@ -158,10 +154,8 @@ public class PostViewModel extends ViewModel { this.userWhere = userWhere; this.postEnricher = postEnricher; - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - postFilterLiveData = new MutableLiveData<>(); - postFilterLiveData.postValue(postFilter); + sortTypeLiveData = new MutableLiveData<>(sortType); + postFilterLiveData = new MutableLiveData<>(postFilter); sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData); @@ -204,10 +198,8 @@ public class PostViewModel extends ViewModel { this.trendingSource = trendingSource; this.postEnricher = postEnricher; - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - postFilterLiveData = new MutableLiveData<>(); - postFilterLiveData.postValue(postFilter); + sortTypeLiveData = new MutableLiveData<>(sortType); + postFilterLiveData = new MutableLiveData<>(postFilter); sortTypeAndPostFilterLiveData = new SortTypeAndPostFilterLiveData(sortTypeLiveData, postFilterLiveData); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterDao.java b/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterDao.java index 42cb8d4f..c5580fbb 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterDao.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterDao.java @@ -6,6 +6,7 @@ import androidx.room.Delete; import androidx.room.Insert; import androidx.room.OnConflictStrategy; import androidx.room.Query; +import androidx.room.Transaction; import java.util.List; @@ -36,7 +37,11 @@ public interface PostFilterDao { List getAllPostFilters(); @Query("SELECT * FROM post_filter WHERE post_filter.name IN " + - "(SELECT post_filter_usage.name FROM post_filter_usage WHERE (usage = :usage AND name_of_usage = :nameOfUsage) " + + "(SELECT post_filter_usage.name FROM post_filter_usage WHERE (usage = :usage AND name_of_usage = :nameOfUsage COLLATE NOCASE) " + "OR (usage =:usage AND name_of_usage = '--'))") List getValidPostFilters(int usage, String nameOfUsage); + + @Transaction + @Query("SELECT * FROM post_filter ORDER BY name") + public LiveData> getAllPostFilterWithUsageLiveData(); } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterWithUsage.java b/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterWithUsage.java new file mode 100644 index 00000000..f9d0b4ec --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterWithUsage.java @@ -0,0 +1,16 @@ +package eu.toldi.infinityforlemmy.postfilter; + +import androidx.room.Embedded; +import androidx.room.Relation; + +import java.util.List; + +public class PostFilterWithUsage { + @Embedded + public PostFilter postFilter; + @Relation( + parentColumn = "name", + entityColumn = "name" + ) + public List postFilterUsages; +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterWithUsageViewModel.java similarity index 55% rename from app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterViewModel.java rename to app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterWithUsageViewModel.java index a1a428db..aec171ce 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/postfilter/PostFilterWithUsageViewModel.java @@ -8,15 +8,16 @@ import java.util.List; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; -public class PostFilterViewModel extends ViewModel { - private LiveData> mPostFilterListLiveData; - public PostFilterViewModel(RedditDataRoomDatabase redditDataRoomDatabase) { - mPostFilterListLiveData = redditDataRoomDatabase.postFilterDao().getAllPostFiltersLiveData(); +public class PostFilterWithUsageViewModel extends ViewModel { + private LiveData> mPostFilterWithUsageListLiveData; + + public PostFilterWithUsageViewModel(RedditDataRoomDatabase redditDataRoomDatabase) { + mPostFilterWithUsageListLiveData = redditDataRoomDatabase.postFilterDao().getAllPostFilterWithUsageLiveData(); } - public LiveData> getPostFilterListLiveData() { - return mPostFilterListLiveData; + public LiveData> getPostFilterWithUsageListLiveData() { + return mPostFilterWithUsageListLiveData; } public static class Factory extends ViewModelProvider.NewInstanceFactory { @@ -30,7 +31,7 @@ public class PostFilterViewModel extends ViewModel { @Override public T create(Class modelClass) { //noinspection unchecked - return (T) new PostFilterViewModel(mRedditDataRoomDatabase); + return (T) new PostFilterWithUsageViewModel(mRedditDataRoomDatabase); } } -} +} \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/DeleteRecentSearchQuery.java b/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/DeleteRecentSearchQuery.java deleted file mode 100644 index 39069eae..00000000 --- a/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/DeleteRecentSearchQuery.java +++ /dev/null @@ -1,44 +0,0 @@ -package eu.toldi.infinityforlemmy.recentsearchquery; - -import android.os.AsyncTask; - -import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; - -public class DeleteRecentSearchQuery { - public interface DeleteRecentSearchQueryListener { - void success(); - } - - public static void deleteRecentSearchQueryListener(RedditDataRoomDatabase redditDataRoomDatabase, - RecentSearchQuery recentSearchQuery, - DeleteRecentSearchQueryListener deleteRecentSearchQueryListener) { - new DeleteRecentSearchQueryAsyncTask(redditDataRoomDatabase, recentSearchQuery, deleteRecentSearchQueryListener).execute(); - } - - private static class DeleteRecentSearchQueryAsyncTask extends AsyncTask { - - private RecentSearchQueryDao recentSearchQueryDao; - private RecentSearchQuery recentSearchQuery; - private DeleteRecentSearchQueryListener deleteRecentSearchQueryListener; - - public DeleteRecentSearchQueryAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - RecentSearchQuery recentSearchQuery, - DeleteRecentSearchQueryListener deleteRecentSearchQueryListener) { - this.recentSearchQueryDao = redditDataRoomDatabase.recentSearchQueryDao(); - this.recentSearchQuery = recentSearchQuery; - this.deleteRecentSearchQueryListener = deleteRecentSearchQueryListener; - } - - @Override - protected Void doInBackground(Void... voids) { - recentSearchQueryDao.deleteRecentSearchQueries(recentSearchQuery); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteRecentSearchQueryListener.success(); - } - } -} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/InsertRecentSearchQuery.java b/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/InsertRecentSearchQuery.java index 6b1ee7e5..fd721ef0 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/InsertRecentSearchQuery.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/InsertRecentSearchQuery.java @@ -1,8 +1,9 @@ package eu.toldi.infinityforlemmy.recentsearchquery; -import android.os.AsyncTask; +import android.os.Handler; import java.util.List; +import java.util.concurrent.Executor; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; @@ -11,28 +12,13 @@ public class InsertRecentSearchQuery { void success(); } - public static void insertRecentSearchQueryListener(RedditDataRoomDatabase redditDataRoomDatabase, String username, - String recentSearchQuery, InsertRecentSearchQueryListener insertRecentSearchQueryListener) { - new InsertRecentSearchQueryAsyncTask(redditDataRoomDatabase, username, recentSearchQuery, insertRecentSearchQueryListener).execute(); - } - - private static class InsertRecentSearchQueryAsyncTask extends AsyncTask { - - private RecentSearchQueryDao recentSearchQueryDao; - private String username; - private String recentSearchQuery; - private InsertRecentSearchQueryListener insertRecentSearchQueryListener; - - public InsertRecentSearchQueryAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String username, - String recentSearchQuery, InsertRecentSearchQueryListener insertRecentSearchQueryListener) { - this.recentSearchQueryDao = redditDataRoomDatabase.recentSearchQueryDao(); - this.username = username; - this.recentSearchQuery = recentSearchQuery; - this.insertRecentSearchQueryListener = insertRecentSearchQueryListener; - } - - @Override - protected Void doInBackground(Void... voids) { + public static void insertRecentSearchQueryListener(Executor executor, Handler handler, + RedditDataRoomDatabase redditDataRoomDatabase, + String username, + String recentSearchQuery, + InsertRecentSearchQueryListener insertRecentSearchQueryListener) { + executor.execute(() -> { + RecentSearchQueryDao recentSearchQueryDao = redditDataRoomDatabase.recentSearchQueryDao(); List recentSearchQueries = recentSearchQueryDao.getAllRecentSearchQueries(username); if (recentSearchQueries.size() >= 5) { for (int i = 4; i < recentSearchQueries.size(); i++) { @@ -41,13 +27,8 @@ public class InsertRecentSearchQuery { } recentSearchQueryDao.insert(new RecentSearchQuery(username, recentSearchQuery)); - return null; - } - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - insertRecentSearchQueryListener.success(); - } + handler.post(insertRecentSearchQueryListener::success); + }); } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/RecentSearchQueryDao.java b/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/RecentSearchQueryDao.java index 1fd7dfde..b93952ab 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/RecentSearchQueryDao.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/recentsearchquery/RecentSearchQueryDao.java @@ -20,6 +20,9 @@ public interface RecentSearchQueryDao { @Query("SELECT * FROM recent_search_queries WHERE username = :username ORDER BY time DESC") List getAllRecentSearchQueries(String username); + @Query("DELETE FROM recent_search_queries WHERE username = :username") + void deleteAllRecentSearchQueries(String username); + @Delete void deleteRecentSearchQueries(RecentSearchQuery recentSearchQuery); } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/services/DownloadRedditVideoService.java b/app/src/main/java/eu/toldi/infinityforlemmy/services/DownloadRedditVideoService.java index 89d768bd..cb6035bc 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/services/DownloadRedditVideoService.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/services/DownloadRedditVideoService.java @@ -26,6 +26,8 @@ import android.os.Message; import android.os.Process; import android.provider.MediaStore; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.app.NotificationChannelCompat; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; @@ -83,6 +85,7 @@ public class DownloadRedditVideoService extends Service { private ServiceHandler serviceHandler; private NotificationManagerCompat notificationManager; private NotificationCompat.Builder builder; + private final String[] possibleAudioUrlSuffices = new String[]{"/DASH_AUDIO_128.mp4", "/DASH_audio.mp4", "/DASH_audio", "/audio.mp4", "/audio"}; public DownloadRedditVideoService() { } @@ -95,7 +98,9 @@ public class DownloadRedditVideoService extends Service { public void handleMessage(Message msg) { Bundle intent = msg.getData(); String videoUrl = intent.getString(EXTRA_VIDEO_URL); - String audioUrl = Build.VERSION.SDK_INT > Build.VERSION_CODES.N ? videoUrl.substring(0, videoUrl.lastIndexOf('/')) + "/DASH_audio.mp4" : null; + + String audioUrlPrefix = Build.VERSION.SDK_INT > Build.VERSION_CODES.N ? videoUrl.substring(0, videoUrl.lastIndexOf('/')) : null; + String subredditName = intent.getString(EXTRA_SUBREDDIT); String fileNameWithoutExtension = subredditName + "-" + intent.getString(EXTRA_POST_ID); boolean isNsfw = intent.getBoolean(EXTRA_IS_NSFW, false); @@ -104,7 +109,8 @@ public class DownloadRedditVideoService extends Service { final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() { long time = 0; - @Override public void update(long bytesRead, long contentLength, boolean done) { + @Override + public void update(long bytesRead, long contentLength, boolean done) { if (!done) { if (contentLength != -1) { long currentTime = System.currentTimeMillis(); @@ -129,7 +135,7 @@ public class DownloadRedditVideoService extends Service { retrofit = retrofit.newBuilder().client(client).build(); - DownloadFile downloadFile = retrofit.create(DownloadFile.class); + DownloadFile downloadFileRetrofit = retrofit.create(DownloadFile.class); boolean separateDownloadFolder = sharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false); @@ -138,7 +144,7 @@ public class DownloadRedditVideoService extends Service { String destinationFileName = fileNameWithoutExtension + ".mp4"; try { - Response videoResponse = downloadFile.downloadFile(videoUrl).execute(); + Response videoResponse = downloadFileRetrofit.downloadFile(videoUrl).execute(); if (videoResponse.isSuccessful() && videoResponse.body() != null) { String externalCacheDirectoryPath = externalCacheDirectory.getAbsolutePath() + "/"; String destinationFileDirectory; @@ -218,13 +224,13 @@ public class DownloadRedditVideoService extends Service { return; } - if (audioUrl != null) { - Response audioResponse = downloadFile.downloadFile(audioUrl).execute(); + if (audioUrlPrefix != null) { + ResponseBody audioResponse = getAudioResponse(downloadFileRetrofit, audioUrlPrefix, 0); String outputFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + ".mp4"; - if (audioResponse.isSuccessful() && audioResponse.body() != null) { + if (audioResponse != null) { String audioFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp3"; - String savedAudioFilePath = writeResponseBodyToDisk(audioResponse.body(), audioFilePath); + String savedAudioFilePath = writeResponseBodyToDisk(audioResponse, audioFilePath); if (savedAudioFilePath == null) { downloadFinished(null, ERROR_AUDIO_FILE_CANNOT_SAVE, randomNotificationIdOffset); return; @@ -298,6 +304,22 @@ public class DownloadRedditVideoService extends Service { } } + @Nullable + private ResponseBody getAudioResponse(DownloadFile downloadFileRetrofit, @NonNull String audioUrlPrefix, int audioSuffixIndex) throws IOException { + if (audioSuffixIndex >= possibleAudioUrlSuffices.length) { + return null; + } + + String audioUrl = audioUrlPrefix + possibleAudioUrlSuffices[audioSuffixIndex]; + Response audioResponse = downloadFileRetrofit.downloadFile(audioUrl).execute(); + ResponseBody responseBody = audioResponse.body(); + if (audioResponse.isSuccessful() && responseBody != null) { + return responseBody; + } + + return getAudioResponse(downloadFileRetrofit, audioUrlPrefix, audioSuffixIndex + 1); + } + private String writeResponseBodyToDisk(ResponseBody body, String filePath) { try { File file = new File(filePath); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/settings/MainPreferenceFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/settings/MainPreferenceFragment.java index 640d56d5..c2d99b97 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/settings/MainPreferenceFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/settings/MainPreferenceFragment.java @@ -8,6 +8,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.biometric.BiometricManager; import androidx.preference.Preference; @@ -19,6 +20,10 @@ import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.activities.PostFilterPreferenceActivity; import eu.toldi.infinityforlemmy.customviews.CustomFontPreferenceFragmentCompat; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; +import eu.toldi.infinityforlemmy.activities.CommentFilterPreferenceActivity; +import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; +import eu.toldi.infinityforlemmy.activities.PostFilterPreferenceActivity; +import eu.toldi.infinityforlemmy.customviews.CustomFontPreferenceFragmentCompat; public class MainPreferenceFragment extends CustomFontPreferenceFragmentCompat { @@ -33,6 +38,7 @@ public class MainPreferenceFragment extends CustomFontPreferenceFragmentCompat { Preference securityPreference = findPreference(SharedPreferencesUtils.SECURITY); Preference postFilterPreference = findPreference(SharedPreferencesUtils.POST_FILTER); + Preference commentFilterPreference = findPreference(SharedPreferencesUtils.COMMENT_FILTER); Preference privacyPolicyPreference = findPreference(SharedPreferencesUtils.PRIVACY_POLICY_KEY); Preference redditUserAgreementPreference = findPreference(SharedPreferencesUtils.REDDIT_USER_AGREEMENT_KEY); @@ -50,5 +56,16 @@ public class MainPreferenceFragment extends CustomFontPreferenceFragmentCompat { return true; }); } + + if (commentFilterPreference != null) { + commentFilterPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(@NonNull Preference preference) { + Intent intent = new Intent(activity, CommentFilterPreferenceActivity.class); + activity.startActivity(intent); + return true; + } + }); + } } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/shortcut/ShortcutManager.java b/app/src/main/java/eu/toldi/infinityforlemmy/shortcut/ShortcutManager.java new file mode 100644 index 00000000..77532171 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/shortcut/ShortcutManager.java @@ -0,0 +1,37 @@ +package eu.toldi.infinityforlemmy.shortcut; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; + +import androidx.annotation.NonNull; +import androidx.core.content.pm.ShortcutInfoCompat; +import androidx.core.content.pm.ShortcutManagerCompat; +import androidx.core.graphics.drawable.IconCompat; + +import eu.toldi.infinityforlemmy.BuildConfig; +import eu.toldi.infinityforlemmy.activities.ViewSubredditDetailActivity; + +public class ShortcutManager { + private static ShortcutInfoCompat getInfo(Context context, @NonNull String subreddit, @NonNull Bitmap icon) { + final Intent shortcut = new Intent(context, ViewSubredditDetailActivity.class); + shortcut.setPackage(context.getPackageName()); + shortcut.setAction(Intent.ACTION_MAIN); + shortcut.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + shortcut.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, subreddit); + + String shortcutId = BuildConfig.APPLICATION_ID + ".shortcut." + subreddit; + String subredditName = subreddit; + return new ShortcutInfoCompat.Builder(context, shortcutId) + .setIntent(shortcut) + .setShortLabel(subredditName) + .setAlwaysBadged() + .setIcon(IconCompat.createWithBitmap(icon)) + .build(); + } + + public static boolean requestPinShortcut(Context context, @NonNull String subreddit, @NonNull Bitmap icon) { + return ShortcutManagerCompat.requestPinShortcut(context, getInfo(context, subreddit, icon), null); + } +} + diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/subreddit/SubredditListingViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/subreddit/SubredditListingViewModel.java index 4aa15f13..aa56e687 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/subreddit/SubredditListingViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/subreddit/SubredditListingViewModel.java @@ -31,8 +31,7 @@ public class SubredditListingViewModel extends ViewModel { hasSubredditLiveData = Transformations.switchMap(subredditListingDataSourceFactory.getSubredditListingDataSourceMutableLiveData(), SubredditListingDataSource::hasSubredditLiveData); - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); + sortTypeLiveData = new MutableLiveData<>(sortType); PagedList.Config pagedListConfig = (new PagedList.Config.Builder()) diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/subscribedsubreddit/SubscribedSubredditViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/subscribedsubreddit/SubscribedSubredditViewModel.java index 763a8de5..ed62d61a 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/subscribedsubreddit/SubscribedSubredditViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/subscribedsubreddit/SubscribedSubredditViewModel.java @@ -23,8 +23,7 @@ public class SubscribedSubredditViewModel extends AndroidViewModel { public SubscribedSubredditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { super(application); mSubscribedSubredditRepository = new SubscribedSubredditRepository(redditDataRoomDatabase, accountName); - searchQueryLiveData = new MutableLiveData<>(); - searchQueryLiveData.postValue(""); + searchQueryLiveData = new MutableLiveData<>(""); mAllSubscribedSubreddits = Transformations.switchMap(searchQueryLiveData, searchQuery -> mSubscribedSubredditRepository.getAllSubscribedSubredditsWithSearchQuery(searchQuery)); mAllFavoriteSubscribedSubreddits = Transformations.switchMap(searchQueryLiveData, searchQuery -> mSubscribedSubredditRepository.getAllFavoriteSubscribedSubredditsWithSearchQuery(searchQuery)); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/subscribeduser/SubscribedUserViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/subscribeduser/SubscribedUserViewModel.java index a92724d8..6310170c 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/subscribeduser/SubscribedUserViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/subscribeduser/SubscribedUserViewModel.java @@ -23,8 +23,7 @@ public class SubscribedUserViewModel extends AndroidViewModel { public SubscribedUserViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { super(application); mSubscribedUserRepository = new SubscribedUserRepository(redditDataRoomDatabase, accountName); - searchQueryLiveData = new MutableLiveData<>(); - searchQueryLiveData.postValue(""); + searchQueryLiveData = new MutableLiveData<>(""); mAllSubscribedUsers = Transformations.switchMap(searchQueryLiveData, searchQuery -> mSubscribedUserRepository.getAllSubscribedUsersWithSearchQuery(searchQuery)); mAllFavoriteSubscribedUsers = Transformations.switchMap(searchQueryLiveData, searchQuery -> mSubscribedUserRepository.getAllFavoriteSubscribedUsersWithSearchQuery(searchQuery)); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/user/UserListingViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/user/UserListingViewModel.java index 58e3b799..a3e6b241 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/user/UserListingViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/user/UserListingViewModel.java @@ -31,8 +31,7 @@ public class UserListingViewModel extends ViewModel { hasUserLiveData = Transformations.switchMap(userListingDataSourceFactory.getUserListingDataSourceMutableLiveData(), UserListingDataSource::hasUserLiveData); - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); + sortTypeLiveData = new MutableLiveData<>(sortType); PagedList.Config pagedListConfig = (new PagedList.Config.Builder()) diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/utils/APIUtils.java b/app/src/main/java/eu/toldi/infinityforlemmy/utils/APIUtils.java index 154c3e42..52c9bd48 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/utils/APIUtils.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/utils/APIUtils.java @@ -1,5 +1,4 @@ package eu.toldi.infinityforlemmy.utils; - import android.util.Base64; import java.util.HashMap; @@ -117,11 +116,6 @@ public class APIUtils { public static final String REFERER_KEY = "Referer"; public static final String REVEDDIT_REFERER = "https://www.reveddit.com/"; - /*public static final String HOST_KEY = "Host"; - public static final String REDGIFS_HOST = "api.redgifs.com"; - public static final String CONTENT_TYPE_KEY = "Content-Type"; - public static final String */ - public static Map getHttpBasicAuthHeader() { Map params = new HashMap<>(); String credentials = String.format("%s:%s", APIUtils.CLIENT_ID, ""); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/utils/CustomThemeSharedPreferencesUtils.java b/app/src/main/java/eu/toldi/infinityforlemmy/utils/CustomThemeSharedPreferencesUtils.java index 3998827b..1389d4ac 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/utils/CustomThemeSharedPreferencesUtils.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/utils/CustomThemeSharedPreferencesUtils.java @@ -29,6 +29,8 @@ public class CustomThemeSharedPreferencesUtils { public static final String BACKGROUND_COLOR = "backgroundColor"; public static final String CARD_VIEW_BACKGROUND_COLOR = "cardViewBackgroundColor"; public static final String READ_POST_CARD_VIEW_BACKGROUND_COLOR = "readPostCardViewBackgroundColor"; + public static final String FILLED_CARD_VIEW_BACKGROUND_COLOR = "filledCardViewBackgroundColor"; + public static final String READ_POST_FILLED_CARD_VIEW_BACKGROUND_COLOR = "readPostFilledCardViewBackgroundColor"; public static final String COMMENT_BACKGROUND_COLOR = "commentBackgroundColor"; public static final String BOTTOM_APP_BAR_BACKGROUND_COLOR = "bottomAppBarBackgroundColor"; public static final String PRIMARY_ICON_COLOR = "primaryIconColor"; @@ -113,6 +115,8 @@ public class CustomThemeSharedPreferencesUtils { editor.putInt(BACKGROUND_COLOR, customTheme.backgroundColor); editor.putInt(CARD_VIEW_BACKGROUND_COLOR, customTheme.cardViewBackgroundColor); editor.putInt(READ_POST_CARD_VIEW_BACKGROUND_COLOR, customTheme.readPostCardViewBackgroundColor); + editor.putInt(FILLED_CARD_VIEW_BACKGROUND_COLOR, customTheme.filledCardViewBackgroundColor); + editor.putInt(READ_POST_FILLED_CARD_VIEW_BACKGROUND_COLOR, customTheme.readPostFilledCardViewBackgroundColor); editor.putInt(COMMENT_BACKGROUND_COLOR, customTheme.commentBackgroundColor); editor.putInt(BOTTOM_APP_BAR_BACKGROUND_COLOR, customTheme.bottomAppBarBackgroundColor); editor.putInt(PRIMARY_ICON_COLOR, customTheme.primaryIconColor); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/utils/MaterialYouUtils.java b/app/src/main/java/eu/toldi/infinityforlemmy/utils/MaterialYouUtils.java index d39e618d..981c4899 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/utils/MaterialYouUtils.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/utils/MaterialYouUtils.java @@ -93,6 +93,7 @@ public class MaterialYouUtils { lightTheme.colorPrimaryLightTheme = lightTheme.colorPrimary; lightTheme.backgroundColor = context.getColor(android.R.color.system_neutral1_50); lightTheme.cardViewBackgroundColor = context.getColor(android.R.color.system_neutral2_10); + lightTheme.filledCardViewBackgroundColor = lightTheme.cardViewBackgroundColor; lightTheme.commentBackgroundColor = context.getColor(android.R.color.system_neutral2_10); lightTheme.awardedCommentBackgroundColor = context.getColor(android.R.color.system_neutral2_10); lightTheme.bottomAppBarBackgroundColor = lightTheme.colorPrimary; @@ -123,6 +124,7 @@ public class MaterialYouUtils { darkTheme.colorPrimaryLightTheme = lightTheme.colorPrimary; darkTheme.backgroundColor = context.getColor(android.R.color.system_neutral1_900); darkTheme.cardViewBackgroundColor = context.getColor(android.R.color.system_neutral2_800); + darkTheme.filledCardViewBackgroundColor = darkTheme.cardViewBackgroundColor; darkTheme.commentBackgroundColor = darkTheme.cardViewBackgroundColor; darkTheme.awardedCommentBackgroundColor = darkTheme.cardViewBackgroundColor; darkTheme.bottomAppBarBackgroundColor = darkTheme.colorPrimary; @@ -189,6 +191,7 @@ public class MaterialYouUtils { lightTheme.colorPrimaryLightTheme = colorPrimaryInt; lightTheme.backgroundColor = backgroundColor; lightTheme.cardViewBackgroundColor = cardViewBackgroundColor; + lightTheme.filledCardViewBackgroundColor = cardViewBackgroundColor; lightTheme.commentBackgroundColor = cardViewBackgroundColor; lightTheme.awardedCommentBackgroundColor = cardViewBackgroundColor; lightTheme.bottomAppBarBackgroundColor = colorPrimaryInt; diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/utils/SharedPreferencesUtils.java b/app/src/main/java/eu/toldi/infinityforlemmy/utils/SharedPreferencesUtils.java index a362cc39..568e2393 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/utils/SharedPreferencesUtils.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/utils/SharedPreferencesUtils.java @@ -89,6 +89,7 @@ public class SharedPreferencesUtils { public static final int POST_LAYOUT_COMPACT = 1; public static final int POST_LAYOUT_GALLERY = 2; public static final int POST_LAYOUT_CARD_2 = 3; + public static final int POST_LAYOUT_CARD_3 = 4; public static final String FRONT_PAGE_SCROLLED_POSITION_SHARED_PREFERENCES_FILE = "eu.toldi.infinityforlemmy.front_page_scrolled_position"; public static final String FRONT_PAGE_SCROLLED_POSITION_FRONT_PAGE_BASE = "_front_page"; @@ -233,6 +234,8 @@ public class SharedPreferencesUtils { public static final String EASIER_TO_WATCH_IN_FULL_SCREEN = "easier_to_watch_in_full_screen"; public static final String HIDE_THE_NUMBER_OF_VOTES_IN_COMMENTS = "hide_the_number_of_votes_in_comments"; public static final String COMMENT_DIVIDER_TYPE = "comment_divider_type"; + public static final String SUBSCRIBED_THINGS_SYNC_TIME = "subscribed_things_sync_time"; + public static final String COMMENT_FILTER = "comment_filter"; public static final String DEFAULT_PREFERENCES_FILE = "eu.toldi.infinityforlemmy_preferences"; public static final String MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE = "eu.toldi.infinityforlemmy.main_page_tabs"; @@ -387,7 +390,7 @@ public class SharedPreferencesUtils { public static final String INTERNAL_SHARED_PREFERENCES_FILE = "eu.toldi.infinityforlemmy.internal"; public static final String HAS_REQUESTED_NOTIFICATION_PERMISSION = "has_requested_notification_permission"; - public static final String DO_NOT_SHOW_REDDIT_API_INFO_AGAIN = "do_not_show_reddit_api_info_again"; + public static final String DO_NOT_SHOW_REDDIT_API_INFO_V2_AGAIN = "do_not_show_reddit_api_info_v2_again"; //Legacy Settings public static final String MAIN_PAGE_TAB_1_TITLE_LEGACY = "main_page_tab_1_title"; diff --git a/app/src/main/res/drawable-night-xxxhdpi/splash_branding.png b/app/src/main/res/drawable-night-xxxhdpi/splash_branding.png new file mode 100644 index 0000000000000000000000000000000000000000..ff0c0130c624218682fa598e19fe0fa97f43c76e GIT binary patch literal 38940 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 F{sO)5$)5lK literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/splash_branding.png b/app/src/main/res/drawable-xxxhdpi/splash_branding.png new file mode 100644 index 0000000000000000000000000000000000000000..ff7afa74e5c518f9cb38f27be4f24e948b10005e GIT binary patch literal 31997 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
  • rXnKKG#ntmQ% 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/exo_player_control_view_background.xml b/app/src/main/res/drawable/exo_player_control_view_background.xml new file mode 100644 index 00000000..b5688638 --- /dev/null +++ b/app/src/main/res/drawable/exo_player_control_view_background.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_back_24dp.xml b/app/src/main/res/drawable/ic_arrow_back_24dp.xml new file mode 100644 index 00000000..a2da1830 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_back_24dp.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_all_24.xml b/app/src/main/res/drawable/ic_delete_all_24.xml new file mode 100644 index 00000000..11007c22 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_all_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_downvote_24dp.xml b/app/src/main/res/drawable/ic_downvote_24dp.xml new file mode 100644 index 00000000..ba411b7f --- /dev/null +++ b/app/src/main/res/drawable/ic_downvote_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_downvote_filled_24dp.xml b/app/src/main/res/drawable/ic_downvote_filled_24dp.xml new file mode 100644 index 00000000..16545ced --- /dev/null +++ b/app/src/main/res/drawable/ic_downvote_filled_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_fast_forward_24dp.xml b/app/src/main/res/drawable/ic_fast_forward_24dp.xml new file mode 100644 index 00000000..30d811c6 --- /dev/null +++ b/app/src/main/res/drawable/ic_fast_forward_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_fast_rewind_24dp.xml b/app/src/main/res/drawable/ic_fast_rewind_24dp.xml new file mode 100644 index 00000000..da3b8d45 --- /dev/null +++ b/app/src/main/res/drawable/ic_fast_rewind_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_file_download_toolbar_white_24dp.xml b/app/src/main/res/drawable/ic_file_download_toolbar_white_24dp.xml index 8a9cfa3c..083d10a9 100644 --- a/app/src/main/res/drawable/ic_file_download_toolbar_white_24dp.xml +++ b/app/src/main/res/drawable/ic_file_download_toolbar_white_24dp.xml @@ -1,5 +1,10 @@ - + android:tint="#FFFFFF" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" + xmlns:android="http://schemas.android.com/apk/res/android"> + diff --git a/app/src/main/res/drawable/ic_mute_24dp.xml b/app/src/main/res/drawable/ic_mute_24dp.xml index ff764c78..4d514f2d 100644 --- a/app/src/main/res/drawable/ic_mute_24dp.xml +++ b/app/src/main/res/drawable/ic_mute_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:fillColor="@android:color/white" + android:pathData="M3.63,3.63c-0.39,0.39 -0.39,1.02 0,1.41L7.29,8.7 7,9L4,9c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1h3l3.29,3.29c0.63,0.63 1.71,0.18 1.71,-0.71v-4.17l4.18,4.18c-0.49,0.37 -1.02,0.68 -1.6,0.91 -0.36,0.15 -0.58,0.53 -0.58,0.92 0,0.72 0.73,1.18 1.39,0.91 0.8,-0.33 1.55,-0.77 2.22,-1.31l1.34,1.34c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L5.05,3.63c-0.39,-0.39 -1.02,-0.39 -1.42,0zM19,12c0,0.82 -0.15,1.61 -0.41,2.34l1.53,1.53c0.56,-1.17 0.88,-2.48 0.88,-3.87 0,-3.83 -2.4,-7.11 -5.78,-8.4 -0.59,-0.23 -1.22,0.23 -1.22,0.86v0.19c0,0.38 0.25,0.71 0.61,0.85C17.18,6.54 19,9.06 19,12zM10.29,5.71l-0.17,0.17L12,7.76L12,6.41c0,-0.89 -1.08,-1.33 -1.71,-0.7zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v1.79l2.48,2.48c0.01,-0.08 0.02,-0.16 0.02,-0.24z" /> diff --git a/app/src/main/res/drawable/ic_mute_white_rounded_24dp.xml b/app/src/main/res/drawable/ic_mute_white_rounded_24dp.xml deleted file mode 100644 index bc45d400..00000000 --- a/app/src/main/res/drawable/ic_mute_white_rounded_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_pause_white_rounded_24dp.xml b/app/src/main/res/drawable/ic_pause_24dp.xml similarity index 100% rename from app/src/main/res/drawable/ic_pause_white_rounded_24dp.xml rename to app/src/main/res/drawable/ic_pause_24dp.xml diff --git a/app/src/main/res/drawable/ic_play_arrow_white_rounded_24dp.xml b/app/src/main/res/drawable/ic_play_arrow_24dp.xml similarity index 100% rename from app/src/main/res/drawable/ic_play_arrow_white_rounded_24dp.xml rename to app/src/main/res/drawable/ic_play_arrow_24dp.xml diff --git a/app/src/main/res/drawable/ic_unmute_24dp.xml b/app/src/main/res/drawable/ic_unmute_24dp.xml index d2c9bb24..e54196ee 100644 --- a/app/src/main/res/drawable/ic_unmute_24dp.xml +++ b/app/src/main/res/drawable/ic_unmute_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:fillColor="@android:color/white" + android:pathData="M3,10v4c0,0.55 0.45,1 1,1h3l3.29,3.29c0.63,0.63 1.71,0.18 1.71,-0.71L12,6.41c0,-0.89 -1.08,-1.34 -1.71,-0.71L7,9L4,9c-0.55,0 -1,0.45 -1,1zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,4.45v0.2c0,0.38 0.25,0.71 0.6,0.85C17.18,6.53 19,9.06 19,12s-1.82,5.47 -4.4,6.5c-0.36,0.14 -0.6,0.47 -0.6,0.85v0.2c0,0.63 0.63,1.07 1.21,0.85C18.6,19.11 21,15.84 21,12s-2.4,-7.11 -5.79,-8.4c-0.58,-0.23 -1.21,0.22 -1.21,0.85z" /> diff --git a/app/src/main/res/drawable/ic_unmute_white_rounded_24dp.xml b/app/src/main/res/drawable/ic_unmute_white_rounded_24dp.xml deleted file mode 100644 index 3afb6532..00000000 --- a/app/src/main/res/drawable/ic_unmute_white_rounded_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_upvote_24dp.xml b/app/src/main/res/drawable/ic_upvote_24dp.xml new file mode 100644 index 00000000..16412f77 --- /dev/null +++ b/app/src/main/res/drawable/ic_upvote_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_upvote_filled_24dp.xml b/app/src/main/res/drawable/ic_upvote_filled_24dp.xml new file mode 100644 index 00000000..bb313a54 --- /dev/null +++ b/app/src/main/res/drawable/ic_upvote_filled_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/splash_screen.xml b/app/src/main/res/drawable/splash_screen.xml index c3ccc627..69ef46bf 100644 --- a/app/src/main/res/drawable/splash_screen.xml +++ b/app/src/main/res/drawable/splash_screen.xml @@ -1,12 +1,19 @@ - + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_comment_filter_preference.xml b/app/src/main/res/layout/activity_comment_filter_preference.xml new file mode 100644 index 00000000..6f2b6051 --- /dev/null +++ b/app/src/main/res/layout/activity_comment_filter_preference.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_comment_filter_usage_listing.xml b/app/src/main/res/layout/activity_comment_filter_usage_listing.xml new file mode 100644 index 00000000..75cfc4e3 --- /dev/null +++ b/app/src/main/res/layout/activity_comment_filter_usage_listing.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_customize_comment_filter.xml b/app/src/main/res/layout/activity_customize_comment_filter.xml new file mode 100644 index 00000000..9153e01a --- /dev/null +++ b/app/src/main/res/layout/activity_customize_comment_filter.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_customize_post_filter.xml b/app/src/main/res/layout/activity_customize_post_filter.xml index 76dcda3d..bb461c76 100644 --- a/app/src/main/res/layout/activity_customize_post_filter.xml +++ b/app/src/main/res/layout/activity_customize_post_filter.xml @@ -51,7 +51,7 @@ android:paddingBottom="8dp" android:paddingStart="16dp" android:paddingEnd="16dp" - style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + android:focusable="true"> + android:textSize="?attr/font_default" /> + + + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> @@ -64,7 +64,7 @@ android:layout_height="wrap_content" android:padding="8dp" android:layout_centerInParent="true" - android:src="@drawable/ic_pause_white_rounded_24dp" + android:src="@drawable/ic_pause_24dp" android:background="@drawable/exo_player_control_button_circular_background" android:clickable="true" android:focusable="true" /> diff --git a/app/src/main/res/layout/exo_autoplay_playback_control_view_legacy.xml b/app/src/main/res/layout/exo_autoplay_playback_control_view_legacy.xml index 52899132..310357ca 100644 --- a/app/src/main/res/layout/exo_autoplay_playback_control_view_legacy.xml +++ b/app/src/main/res/layout/exo_autoplay_playback_control_view_legacy.xml @@ -49,19 +49,21 @@ android:textStyle="bold" android:fontFamily="?attr/font_family" /> - + android:src="@drawable/ic_play_arrow_24dp" /> - + android:src="@drawable/ic_pause_24dp" /> - + + + android:orientation="horizontal" + android:paddingTop="4dp"> - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:strokeWidth="0dp" + app:iconSize="24dp" + app:iconTint="@null" + app:backgroundTint="#22FFFFFF" + android:visibility="gone" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> - + + + + + + + + + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" + app:strokeWidth="0dp" + app:icon="@drawable/ic_video_quality_24dp" + app:iconSize="24dp" + app:iconTint="@null" + app:backgroundTint="#22FFFFFF" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> - + - @@ -65,18 +149,18 @@ android:id="@id/exo_progress" android:layout_width="0dp" android:layout_weight="1" - android:layout_height="26dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" app:bar_height="2dp" - app:scrubber_color="@color/colorAccent" - app:played_color="@color/colorAccent" /> + app:scrubber_color="#FFFFFF" + app:played_color="#FFFFFF" /> @@ -88,47 +172,56 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" + app:contentInsetStart="0dp" android:backgroundTint="#00000000" app:elevation="0dp" android:visibility="gone" style="@style/Widget.MaterialComponents.BottomAppBar"> - - + app:strokeWidth="0dp" + app:icon="@drawable/ic_arrow_back_24dp" + app:iconSize="24dp" + app:iconTint="@null" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:strokeWidth="0dp" + app:icon="@drawable/ic_file_download_toolbar_white_24dp" + app:iconSize="24dp" + app:iconTint="@null" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/playback_speed_image_view_exo_playback_control_view" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:strokeWidth="0dp" + app:icon="@drawable/ic_playback_speed_toolbar_24dp" + app:iconSize="24dp" + app:iconTint="@null" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> - + diff --git a/app/src/main/res/layout/fragment_comment_filter_options_bottom_sheet.xml b/app/src/main/res/layout/fragment_comment_filter_options_bottom_sheet.xml new file mode 100644 index 00000000..011f7d51 --- /dev/null +++ b/app/src/main/res/layout/fragment_comment_filter_options_bottom_sheet.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_comment_filter_usage_options_bottom_sheet.xml b/app/src/main/res/layout/fragment_comment_filter_usage_options_bottom_sheet.xml new file mode 100644 index 00000000..cc9e4926 --- /dev/null +++ b/app/src/main/res/layout/fragment_comment_filter_usage_options_bottom_sheet.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_reddit_api_info_bottom_sheet.xml b/app/src/main/res/layout/fragment_important_info_bottom_sheet.xml similarity index 94% rename from app/src/main/res/layout/fragment_reddit_api_info_bottom_sheet.xml rename to app/src/main/res/layout/fragment_important_info_bottom_sheet.xml index d5f9f28b..06f94a97 100644 --- a/app/src/main/res/layout/fragment_reddit_api_info_bottom_sheet.xml +++ b/app/src/main/res/layout/fragment_important_info_bottom_sheet.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".bottomsheetfragments.RedditAPIInfoBottomSheetFragment"> + tools:context=".bottomsheetfragments.ImportantInfoBottomSheetFragment"> diff --git a/app/src/main/res/layout/fragment_new_comment_filter_usage_bottom_sheet.xml b/app/src/main/res/layout/fragment_new_comment_filter_usage_bottom_sheet.xml new file mode 100644 index 00000000..4f91b851 --- /dev/null +++ b/app/src/main/res/layout/fragment_new_comment_filter_usage_bottom_sheet.xml @@ -0,0 +1,34 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_post_filter_options_bottom_sheet.xml b/app/src/main/res/layout/fragment_post_filter_options_bottom_sheet.xml index a9c9310e..2fa19826 100644 --- a/app/src/main/res/layout/fragment_post_filter_options_bottom_sheet.xml +++ b/app/src/main/res/layout/fragment_post_filter_options_bottom_sheet.xml @@ -33,7 +33,7 @@ android:id="@+id/apply_to_text_view_post_filter_options_bottom_sheet_fragment" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/apply_post_filter_to" + android:text="@string/apply_to" android:textColor="?attr/primaryTextColor" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" diff --git a/app/src/main/res/layout/fragment_post_layot_bottom_sheet.xml b/app/src/main/res/layout/fragment_post_layout_bottom_sheet.xml similarity index 82% rename from app/src/main/res/layout/fragment_post_layot_bottom_sheet.xml rename to app/src/main/res/layout/fragment_post_layout_bottom_sheet.xml index e42263a0..a2882a3a 100644 --- a/app/src/main/res/layout/fragment_post_layot_bottom_sheet.xml +++ b/app/src/main/res/layout/fragment_post_layout_bottom_sheet.xml @@ -44,6 +44,22 @@ android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> + + + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> + style="@style/Widget.Material3.TextInputLayout.OutlinedBox"> - + app:layout_constraintBottom_toBottomOf="parent"> - + - + + + + + app:layout_constraintEnd_toStartOf="@+id/more_button_theme_preview_comments_fragment" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/vote_button_toggle_theme_preview_comments_fragment" + app:layout_constraintTop_toTopOf="parent" /> - + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/more_button_theme_preview_comments_fragment" + app:layout_constraintTop_toTopOf="parent" /> - + style="?attr/materialIconButtonOutlinedStyle" /> - + style="?attr/materialIconButtonOutlinedStyle" /> @@ -311,108 +326,123 @@ android:id="@+id/bottom_constraint_layout_award_background_theme_preview_comments_fragment" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingBottom="12dp" android:paddingStart="4dp" android:paddingEnd="4dp"> - + app:layout_constraintBottom_toBottomOf="parent"> - + - + + + + + app:layout_constraintEnd_toStartOf="@+id/more_button_award_background_theme_preview_comments_fragment" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/vote_button_toggle_award_background_theme_preview_comments_fragment" + app:layout_constraintTop_toTopOf="parent" /> - + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/more_button_award_background_theme_preview_comments_fragment" + app:layout_constraintTop_toTopOf="parent" /> - + style="?attr/materialIconButtonOutlinedStyle" /> - + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/fragment_theme_preview_posts.xml b/app/src/main/res/layout/fragment_theme_preview_posts.xml index 29a0ba95..2c9ad16e 100644 --- a/app/src/main/res/layout/fragment_theme_preview_posts.xml +++ b/app/src/main/res/layout/fragment_theme_preview_posts.xml @@ -237,91 +237,99 @@ app:tint="@android:color/tab_indicator_text" /> + android:layout_height="wrap_content" + android:paddingStart="8dp" + android:paddingEnd="8dp"> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"> - + - + + + + - - + app:layout_constraintStart_toEndOf="@id/vote_button_toggle_theme_preview_posts_fragment" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/comments_count_button_theme_preview_posts_fragment" + app:layout_constraintEnd_toStartOf="@id/share_button_theme_preview_posts_fragment" + style="?attr/materialIconButtonOutlinedStyle" /> - + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_comment.xml b/app/src/main/res/layout/item_comment.xml index 6ca23354..f6f50254 100644 --- a/app/src/main/res/layout/item_comment.xml +++ b/app/src/main/res/layout/item_comment.xml @@ -152,15 +152,18 @@ android:paddingStart="4dp" android:paddingEnd="4dp"> - - - + app:layout_constraintTop_toTopOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintTop_toTopOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintTop_toTopOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_comment_filter_usage_embedded.xml b/app/src/main/res/layout/item_comment_filter_usage_embedded.xml new file mode 100644 index 00000000..e156e968 --- /dev/null +++ b/app/src/main/res/layout/item_comment_filter_usage_embedded.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_comment_filter_with_usage.xml b/app/src/main/res/layout/item_comment_filter_with_usage.xml new file mode 100644 index 00000000..7e35d141 --- /dev/null +++ b/app/src/main/res/layout/item_comment_filter_with_usage.xml @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_card_2_gallery_type.xml b/app/src/main/res/layout/item_post_card_2_gallery_type.xml index 04eb1d0a..0bec1a55 100644 --- a/app/src/main/res/layout/item_post_card_2_gallery_type.xml +++ b/app/src/main/res/layout/item_post_card_2_gallery_type.xml @@ -253,17 +253,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -280,15 +285,18 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_card_2_gallery_type" /> - @@ -307,47 +315,50 @@ app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_card_2_gallery_type" app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_card_2_gallery_type" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_card_2_gallery_type" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_card_2_gallery_type" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_card_2_text.xml b/app/src/main/res/layout/item_post_card_2_text.xml index 92b02913..95bc101d 100644 --- a/app/src/main/res/layout/item_post_card_2_text.xml +++ b/app/src/main/res/layout/item_post_card_2_text.xml @@ -212,17 +212,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -237,17 +242,20 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_card_2_text" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_card_2_text" /> - @@ -263,50 +271,53 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_card_2_text" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_card_2_text" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_card_2_text" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_card_2_text" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_card_2_text" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_card_2_video_autoplay.xml b/app/src/main/res/layout/item_post_card_2_video_autoplay.xml index 3261b471..a8784904 100644 --- a/app/src/main/res/layout/item_post_card_2_video_autoplay.xml +++ b/app/src/main/res/layout/item_post_card_2_video_autoplay.xml @@ -253,17 +253,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -278,17 +283,20 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_card_2_video_autoplay" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_card_2_video_autoplay" /> - @@ -304,49 +312,52 @@ android:visibility="gone" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_card_2_video_autoplay" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_card_2_video_autoplay" /> - - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_card_2_video_autoplay" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_card_2_video_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_card_2_video_autoplay_legacy_controller.xml b/app/src/main/res/layout/item_post_card_2_video_autoplay_legacy_controller.xml index a39dff7a..a8b698d0 100644 --- a/app/src/main/res/layout/item_post_card_2_video_autoplay_legacy_controller.xml +++ b/app/src/main/res/layout/item_post_card_2_video_autoplay_legacy_controller.xml @@ -252,17 +252,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -277,17 +282,20 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_card_2_video_autoplay" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_card_2_video_autoplay" /> - @@ -303,49 +311,52 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_card_2_video_autoplay" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_card_2_video_autoplay" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_card_2_video_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_card_2_video_autoplay" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_card_2_video_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_card_2_with_preview.xml b/app/src/main/res/layout/item_post_card_2_with_preview.xml index b94d9a09..e8e3649a 100644 --- a/app/src/main/res/layout/item_post_card_2_with_preview.xml +++ b/app/src/main/res/layout/item_post_card_2_with_preview.xml @@ -264,17 +264,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -289,17 +294,20 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_card_2_with_preview" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_card_2_with_preview" /> - @@ -315,49 +323,52 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_card_2_with_preview" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_card_2_with_preview" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_card_2_with_preview" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_card_2_with_preview" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_card_2_with_preview" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_card_3_gallery_type.xml b/app/src/main/res/layout/item_post_card_3_gallery_type.xml new file mode 100644 index 00000000..60a44535 --- /dev/null +++ b/app/src/main/res/layout/item_post_card_3_gallery_type.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_card_3_text.xml b/app/src/main/res/layout/item_post_card_3_text.xml new file mode 100644 index 00000000..659b5fae --- /dev/null +++ b/app/src/main/res/layout/item_post_card_3_text.xml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_card_3_video_type_autoplay.xml b/app/src/main/res/layout/item_post_card_3_video_type_autoplay.xml new file mode 100644 index 00000000..556d8dde --- /dev/null +++ b/app/src/main/res/layout/item_post_card_3_video_type_autoplay.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_card_3_video_type_autoplay_legacy_controller.xml b/app/src/main/res/layout/item_post_card_3_video_type_autoplay_legacy_controller.xml new file mode 100644 index 00000000..dced0225 --- /dev/null +++ b/app/src/main/res/layout/item_post_card_3_video_type_autoplay_legacy_controller.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_card_3_with_preview.xml b/app/src/main/res/layout/item_post_card_3_with_preview.xml new file mode 100644 index 00000000..de58dc4e --- /dev/null +++ b/app/src/main/res/layout/item_post_card_3_with_preview.xml @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_compact.xml b/app/src/main/res/layout/item_post_compact.xml index 9db1e435..5fc537a3 100644 --- a/app/src/main/res/layout/item_post_compact.xml +++ b/app/src/main/res/layout/item_post_compact.xml @@ -291,20 +291,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -318,21 +320,21 @@ android:textSize="?attr/font_12" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_compact" + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_compact" app:layout_constraintTop_toTopOf="parent" /> - @@ -347,60 +349,53 @@ android:textStyle="bold" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_compact" + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_compact" app:layout_constraintTop_toTopOf="parent" /> - + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_compact" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_compact" + style="?attr/materialIconButtonOutlinedStyle" /> - + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_compact_right_thumbnail.xml b/app/src/main/res/layout/item_post_compact_right_thumbnail.xml index f3601d08..80bc49e9 100644 --- a/app/src/main/res/layout/item_post_compact_right_thumbnail.xml +++ b/app/src/main/res/layout/item_post_compact_right_thumbnail.xml @@ -288,20 +288,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -315,21 +317,21 @@ android:textSize="?attr/font_12" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_compact_right_thumbnail" + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_compact_right_thumbnail" app:layout_constraintTop_toTopOf="parent" /> - @@ -344,59 +346,52 @@ android:textStyle="bold" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_compact_right_thumbnail" + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_compact_right_thumbnail" app:layout_constraintTop_toTopOf="parent" /> - + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_compact_right_thumbnail" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_compact_right_thumbnail" + style="?attr/materialIconButtonOutlinedStyle" /> - + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_gallery.xml b/app/src/main/res/layout/item_post_detail_gallery.xml index dc905e13..66906951 100644 --- a/app/src/main/res/layout/item_post_detail_gallery.xml +++ b/app/src/main/res/layout/item_post_detail_gallery.xml @@ -249,7 +249,7 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -293,18 +298,21 @@ android:textSize="?attr/font_12" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_detail_gallery" + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_gallery" app:layout_constraintTop_toTopOf="parent" /> - @@ -319,50 +327,53 @@ android:textSize="?attr/font_12" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_detail_gallery" + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_gallery" app:layout_constraintTop_toTopOf="parent" /> - + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_gallery" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_gallery" + style="?attr/materialIconButtonOutlinedStyle" /> - + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_image_and_gif_autoplay.xml b/app/src/main/res/layout/item_post_detail_image_and_gif_autoplay.xml index 55867cd2..4a69a44f 100644 --- a/app/src/main/res/layout/item_post_detail_image_and_gif_autoplay.xml +++ b/app/src/main/res/layout/item_post_detail_image_and_gif_autoplay.xml @@ -273,47 +273,55 @@ android:nestedScrollingEnabled="false" /> + android:paddingStart="4dp" + android:paddingEnd="4dp"> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_image_and_gif_autoplay" + app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/score_text_view_item_post_detail_image_and_gif_autoplay" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_image_and_gif_autoplay" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_detail_image_and_gif_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_image_and_gif_autoplay" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_image_and_gif_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_link.xml b/app/src/main/res/layout/item_post_detail_link.xml index b00f48fc..21efd96a 100644 --- a/app/src/main/res/layout/item_post_detail_link.xml +++ b/app/src/main/res/layout/item_post_detail_link.xml @@ -282,47 +282,55 @@ android:nestedScrollingEnabled="false" /> + android:paddingStart="4dp" + android:paddingEnd="4dp"> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_link" + app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/score_text_view_item_post_detail_link" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_link" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_detail_link" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_link" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_link" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_no_preview.xml b/app/src/main/res/layout/item_post_detail_no_preview.xml index 2881ef77..96699da8 100644 --- a/app/src/main/res/layout/item_post_detail_no_preview.xml +++ b/app/src/main/res/layout/item_post_detail_no_preview.xml @@ -8,13 +8,13 @@ android:background="?attr/cardViewBackgroundColor"> + app:layout_constraintBottom_toTopOf="@+id/author_flair_text_view_item_post_detail_no_preview" + app:layout_constraintStart_toEndOf="@+id/icon_gif_image_view_item_post_detail_no_preview" + + app:layout_constraintTop_toBottomOf="@+id/subreddit_text_view_item_post_detail_no_preview" + app:layout_constraintHorizontal_bias="0" + app:layout_constrainedWidth="true" /> + app:layout_constraintStart_toEndOf="@+id/user_text_view_item_post_detail_no_preview" + app:layout_constraintTop_toBottomOf="@+id/subreddit_text_view_item_post_detail_no_preview" /> + android:paddingStart="4dp" + android:paddingEnd="4dp"> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_no_preview" + app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/score_text_view_item_post_detail_no_preview" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_no_preview" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_detail_no_preview_link" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_no_preview" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_no_preview" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_text.xml b/app/src/main/res/layout/item_post_detail_text.xml index c64f9e67..67dae1d7 100644 --- a/app/src/main/res/layout/item_post_detail_text.xml +++ b/app/src/main/res/layout/item_post_detail_text.xml @@ -235,47 +235,55 @@ + android:paddingStart="4dp" + android:paddingEnd="4dp"> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_text" + app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/score_text_view_item_post_detail_text" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_text" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_detail_text" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_text" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_text" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml b/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml index c2752532..0b259862 100644 --- a/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml +++ b/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml @@ -285,47 +285,55 @@ android:nestedScrollingEnabled="false" /> + android:paddingStart="4dp" + android:paddingEnd="4dp"> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_video_and_gif_preview" + app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/score_text_view_item_post_detail_video_and_gif_preview" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_video_and_gif_preview" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_detail_video_and_gif_preview" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_video_and_gif_preview" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_video_and_gif_preview" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_video_autoplay.xml b/app/src/main/res/layout/item_post_detail_video_autoplay.xml index 77b9a1e4..daeb6b2c 100644 --- a/app/src/main/res/layout/item_post_detail_video_autoplay.xml +++ b/app/src/main/res/layout/item_post_detail_video_autoplay.xml @@ -266,47 +266,55 @@ android:nestedScrollingEnabled="false" /> + android:paddingStart="4dp" + android:paddingEnd="4dp"> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_video_autoplay" + app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/score_text_view_item_post_detail_video_autoplay" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_video_autoplay" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_detail_video_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_video_autoplay" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_video_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_detail_video_autoplay_legacy_controller.xml b/app/src/main/res/layout/item_post_detail_video_autoplay_legacy_controller.xml index e22630b6..33da9144 100644 --- a/app/src/main/res/layout/item_post_detail_video_autoplay_legacy_controller.xml +++ b/app/src/main/res/layout/item_post_detail_video_autoplay_legacy_controller.xml @@ -269,47 +269,55 @@ android:nestedScrollingEnabled="false" /> + android:paddingStart="4dp" + android:paddingEnd="4dp"> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_detail_video_autoplay" + app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintStart_toEndOf="@id/score_text_view_item_post_detail_video_autoplay" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_detail_video_autoplay" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_detail_video_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_detail_video_autoplay" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_detail_video_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_filter.xml b/app/src/main/res/layout/item_post_filter.xml deleted file mode 100644 index 62a5e886..00000000 --- a/app/src/main/res/layout/item_post_filter.xml +++ /dev/null @@ -1,14 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_filter_usage_embedded.xml b/app/src/main/res/layout/item_post_filter_usage_embedded.xml new file mode 100644 index 00000000..e156e968 --- /dev/null +++ b/app/src/main/res/layout/item_post_filter_usage_embedded.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_filter_with_usage.xml b/app/src/main/res/layout/item_post_filter_with_usage.xml new file mode 100644 index 00000000..11a1c705 --- /dev/null +++ b/app/src/main/res/layout/item_post_filter_with_usage.xml @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_post_gallery_type.xml b/app/src/main/res/layout/item_post_gallery_type.xml index 43e36c0a..9f6857a9 100644 --- a/app/src/main/res/layout/item_post_gallery_type.xml +++ b/app/src/main/res/layout/item_post_gallery_type.xml @@ -268,17 +268,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -295,15 +300,18 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_gallery_type" /> - @@ -321,47 +329,50 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_gallery_type" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_gallery_type" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_gallery_type" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_gallery_type" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_text.xml b/app/src/main/res/layout/item_post_text.xml index f5e49f07..73822eaf 100644 --- a/app/src/main/res/layout/item_post_text.xml +++ b/app/src/main/res/layout/item_post_text.xml @@ -246,17 +246,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -271,17 +276,20 @@ android:textStyle="bold" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_text_type" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_text_type" /> - @@ -297,49 +305,52 @@ android:visibility="gone" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_text_type" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_text_type" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_text_type" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_text_type" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_text_type" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_video_type_autoplay.xml b/app/src/main/res/layout/item_post_video_type_autoplay.xml index 51d0083c..22ec8763 100644 --- a/app/src/main/res/layout/item_post_video_type_autoplay.xml +++ b/app/src/main/res/layout/item_post_video_type_autoplay.xml @@ -268,17 +268,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -289,21 +294,24 @@ android:layout_height="wrap_content" android:gravity="center" android:textSize="?attr/font_12" - android:textStyle="bold" android:fontFamily="?attr/font_family" + android:textStyle="bold" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_video_type_autoplay" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_video_type_autoplay" /> - @@ -319,49 +327,52 @@ android:visibility="gone" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_video_type_autoplay" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_video_type_autoplay" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_video_type_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_video_type_autoplay" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_video_type_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_video_type_autoplay_legacy_controller.xml b/app/src/main/res/layout/item_post_video_type_autoplay_legacy_controller.xml index ff6cf720..fb73ba45 100644 --- a/app/src/main/res/layout/item_post_video_type_autoplay_legacy_controller.xml +++ b/app/src/main/res/layout/item_post_video_type_autoplay_legacy_controller.xml @@ -268,17 +268,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -289,21 +294,24 @@ android:layout_height="wrap_content" android:gravity="center" android:textSize="?attr/font_12" - android:textStyle="bold" android:fontFamily="?attr/font_family" + android:textStyle="bold" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_video_type_autoplay" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_video_type_autoplay" /> - @@ -319,49 +327,52 @@ android:visibility="gone" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_video_type_autoplay" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_video_type_autoplay" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_video_type_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_video_type_autoplay" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_video_type_autoplay" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_post_with_preview.xml b/app/src/main/res/layout/item_post_with_preview.xml index 0f90a714..daf7409a 100644 --- a/app/src/main/res/layout/item_post_with_preview.xml +++ b/app/src/main/res/layout/item_post_with_preview.xml @@ -292,17 +292,22 @@ + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> - @@ -313,21 +318,24 @@ android:layout_height="wrap_content" android:gravity="center" android:textSize="?attr/font_12" - android:textStyle="bold" android:fontFamily="?attr/font_family" + android:textStyle="bold" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/plus_button_item_post_with_preview" /> + app:layout_constraintStart_toEndOf="@id/upvote_button_item_post_with_preview" /> - @@ -343,49 +351,52 @@ android:fontFamily="?attr/font_family" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/minus_button_item_post_with_preview" /> + app:layout_constraintStart_toEndOf="@id/downvote_button_item_post_with_preview" /> - + app:layout_constraintStart_toEndOf="@id/downvote_text_view_item_post_with_preview" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintStart_toEndOf="@id/comments_count_button_item_post_with_preview" + app:layout_constraintEnd_toStartOf="@id/share_button_item_post_with_preview" + style="?attr/materialIconButtonOutlinedStyle" /> - + app:layout_constraintEnd_toEndOf="parent" + style="?attr/materialIconButtonOutlinedStyle" /> diff --git a/app/src/main/res/layout/item_recent_search_query.xml b/app/src/main/res/layout/item_recent_search_query.xml index fd851926..e23e7378 100644 --- a/app/src/main/res/layout/item_recent_search_query.xml +++ b/app/src/main/res/layout/item_recent_search_query.xml @@ -1,9 +1,8 @@ - @@ -14,17 +13,21 @@ android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_vertical" + android:gravity="center_vertical" android:fontFamily="?attr/font_family" android:textSize="?attr/font_default" + android:padding="16dp" android:drawablePadding="16dp" /> - + android:padding="16dp" + app:strokeWidth="0dp" + app:iconSize="24dp" + app:iconTint="@null" + style="?attr/materialIconButtonOutlinedStyle" /> \ No newline at end of file diff --git a/app/src/main/res/menu/customize_comment_filter_activity.xml b/app/src/main/res/menu/customize_comment_filter_activity.xml new file mode 100644 index 00000000..8d947f81 --- /dev/null +++ b/app/src/main/res/menu/customize_comment_filter_activity.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/view_subreddit_detail_activity.xml b/app/src/main/res/menu/view_subreddit_detail_activity.xml index fd8565fb..3c8e0f8c 100644 --- a/app/src/main/res/menu/view_subreddit_detail_activity.xml +++ b/app/src/main/res/menu/view_subreddit_detail_activity.xml @@ -38,7 +38,12 @@ + + @@ -54,6 +59,11 @@ android:title="@string/action_share" app:showAsAction="never" /> + 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 literal 4809 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 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 58c5dfcfe2bf647cedc82186b326a9889f2a9329..ade6c09c42a00aad692a1928b0e75aa4e5c77948 100644 GIT binary patch literal 4994 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 literal 4809 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 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index 2f72c89dc69959597a0fa6dc3d4786724266661c..399ba9ad0a4c14b0a3ed3133ae22f5e55eb7c000 100644 GIT binary patch delta 3067 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 JPDHLkV1m&k`u_j` delta 2987 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 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 2f72c89dc69959597a0fa6dc3d4786724266661c..399ba9ad0a4c14b0a3ed3133ae22f5e55eb7c000 100644 GIT binary patch delta 3067 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 JPDHLkV1m&k`u_j` delta 2987 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 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 63b45e6d81ffb3b867a9e8b8a4e8f0d71192b7a9..78eaec8d06482bc669c92468a36287fee2148be1 100644 GIT binary patch literal 7121 zcmV;?8!qIDP)oQbYR`!mEaLXF7?%eK`AriSPPGY0Ad(-+zY zrti@Qq+ewCJHw|8-{}I8${^`H5*P8~={{{SR1mSbzx~7eCjrYm=CK=4hcMp}CiaEAR^H{SuM9uN>^y{ZdL8*b1_(CJQ}4bnG(8LTG08n z8$k@Vd_fhEUdf4<7Dh@X?rs?L;)CnFlV7T%oP%3mMC-ToNouJJNWUZ-^>?$&sS85d z%5>ERq+NFKh-)S1;?@&%RBp7|ls4K;gqRGkCc2c+*c>2?Cy$cP&TP2OUtSMG+o z=t*d2tb(rh1n46A@#`j(xvgjwoDRo!X?QTCcG=p5^+en7o)n1b|4ip}Vc_|t>{l5U zY0bJ$5G<_sPhDsTxN`D?*oe={hi=(6=$CDU{p{6noLlv zShH*t3Z@NHT$4cLKec`gO1F=LPjoNob20)8&g{KU!csX$mM>zo*ZHSp7*b7nwnL=$ zoeYP9m9U?)7W&1Tpk1>E>L<%!cc>D!2hYK}xCGWko1jS?p-`|nU>}%<;J8et_4!#kzIFGQ()V?m_7e(E7?T$!V|Mj%(xsYf6D^ISfDd21$K zI5G(_NqrRcBzQ$-)FfYmAMGRYp!})Ey|ag$GfNcmZ5(W>9Wq5eK{IMDBbyO^tO|Aq z%9$Zbq1pTtv`=h;e)(#K$Dv)iiW|Uoei5|dENB~;f>qw$sPu1*>w^;UWU5l}#=;7YxIM2}2au>JJtVm@CryCLLp3Nl#^1VDnD2q~1Ses7O9R zk?U(_uYz{{4(J{$hHm9r=vJ+RZZ&f^8+Jmy^AIeshvsE3z)v+C4;qqW?e60bXc)(my3Ut2lIdblrP=tU& zt3KBF`@91_-4vap?W`qiv~PxH3-kLW$Cw*BE4ZPPFBqU>uBc`49t1CV43p9`QQj>Y zA7;kkrGBXx(}lGWq-^)Dg6N9$zCEtmyG1+8Ic#L%HPGTLTNfY+{L2;Y7XT{i7S za`7(ApHYAv<3^)mM1NcwGY~K44Z-GuDd;_OE<)q_!>Jy`Qzqltu`e=)jKlUPAH!e% zcOO1^yA0odT8`hot;Fx&o#(GVe0~;Re{>3O|Mf7=p5BIsm|;S@59aR0xXs33)#6cj zrED^)4o$@NCvp|n4G^;;op16Dy?2)ofy>6YBEf&r=r1-N{fiRQa5b|ls)F5cF5DM; zBio}SE*2*S_rc{sY4~TqMEol&0WVA#j$LyLF?ID5NZ7R>u16~2uU$4kv;YyI0n_v=*HNvVl-~NT3|51PjAe`z71pH8JVG|%TYZGzO{9W4(6OTY;7R< z{uJSG#l-e9`E8G20j{#(sf!r|r@~?c7FQsA^F?&rScQ)3E};FYQ}7(mR>qM7lmg4( z5}t`=D;ML_caJN`YzoLdJ-lEJoWo4y@pZt3ttXCb9mm%SKfgH>l}}HAhdJ^MpcOLB zg1D8$WdmY?xR=p7OwSs+V(fnE3y0{zXftp&+6y% z$1f|exM*RcW&*7fiWZLK+ZM|gj8t4#K;%s4oA{2(!9&=#uGc=1==<&cQ~KAI_gfMa zXybd2!i!bAxyvvn&XV}|XXRMRW>`awK#MxZAYs#vG9miRJt70X)%!v<;V-NU*yiE{>11y_S64o5}56hSakD1I2-?R*A>*Kko zIxtc3c{Rki23ZhY{!Qgq2^+NR*l zX+wE{HvZfILoiPKLhTytBXC?>ED#?)()%V2z7_6=0^+`X>+owm+|Dm7*Z=&ha=iZO zaU6O702aRaBt~7@hygFH=NNl=6ITD@DO~)h6d!$g1~b*P7b^k;y~w#d{|dq)7Pp*U#YKd;1al++&IMzgcw=j+d)?}!Ns87&4W4)`Q}uXB%#B#uol%0vTbyb}i) z{C_hUASo-yS4zP^9lA?<(G@R{(B z&rae)7N~y{W%&HP<4DXheQIU_i08%>2f7py$EIA6l%HDb{8Dyv12kgwTOS0*4Z!se zPjSV`&kuNcJ-jb0=f0kNwlQ&*1kHplERY90TZE{pRj6Va6Ujk~zruNsC}g!5#4T!# zXSV~4W9cz>`Fg+*fNhxp&Nrt4W-pj)NIQuDhh`?dHsrF{AkD0^ z=fmpZ8L(PesJte}30ALQI;_^rQeHDc_ZL>-^d9HnJohGs8Z{j@Uh0p z&&#X8vlR3izo{8ApdsU?7!)SF^zpGe7gii(fGJa9HFt*cnjEF`&|+ME-G*Xl z#rmaHvtcl>46Nw!B?_4>g6b`a>$XlI?adjWg>Bo8A~wCK_u3&R6U(DEs#3r|OmU%sDX{?;K6Tp0Yu3I5Ssq z-58Tjj>VN@={Q(60G?+aR$Q0EiOqu7*rHF8>GF$v;2WEzkh{qc4WRc+{z2ms+S!}| z9?-c*MKqTIJUaHpo0kq4lwHMgeq%yRfyn>8v^#z*O@y07=sq^Ox6d}zvD(VsADIU` zHd{`WW%2r798E^o)6*2~$w9Mk>R-0vXK@x>```rHCk|G~-elA;Ku8zj+N1$&T_eJp z%LR2xAC8Z%9OH_9&+`8sY-MUph$&>8dI%-Q2O;m|IM_0R`R9k{!D=Fl35yG0HJ>3b zAF89mwYbw$@pRchOlC7dS6=sw@nLI_&##qpxhOqu>K3(0)NnyTF=h>5=N#Owxq@(V z|6IfN!(}$@-OoR&AfrKGBi?GsOjtcSlLueL^#I$--&qfSgG@*Cr+Rzq=pSjojgE4h&?gamfwk&zhx>y~&W$Q19*^ z+c|gy2nMLJAH)}83=XZ>O1N1TVgqw0;rmYo159In*O-Lc3EG;V{UMTVanT}$>`jKq zrPhlr#8f(0f$JJGKsX0xaM1ZBU$FF6ghRUwjCp7w{_~lz8(Clff2&|uu?UCW+s|by zd1@#8V<*8Ou<<8l3P@WKo^j7Jj%g(<4)_`d;8Q}+0!4`>4A3&DH@u_Ap>ygAWDPCF zvSpRH_P*d}y)HD-|2G5jE^o#MZ(hKr;)@uOTghZTf=(%q!n@-bIJRrz+CbWjbMJhZ zacnPgZFD#<91>`?UfmaS0|;Bu4c?BX(e58R5h;DQVOY*H$Qf6~kvFLdMMYJ3ru+ih zls}3G%I}OAU|qflZBMSifGr0wy`T!Yd4jwWhK;U3Qt!?1VS}krvqCr*{)4%8Xxw7x zfnBZX0~z5%wZ^m4aM1t_%7pCMJ)TiHNbR>BqsLxEE)#xg?pgjSSBQ{1s}jA7_apS+ zdbF&t?BPp&;e2)(!uM{%ptVPkGx4HAMq`W``z$lWCb&m5Fin*o$hd?}AdXER%nPS9 zwl>be(d@==t8X^Zs1Y6v$wHU3mB=1>nhQHC=LBBuKOLX-8OdK4jy|kVh$H_3hCWh` ztj+ro%#6|c_zLLH)?;s|fuIE!wcDm_B|03~fc_f~V93m~$eH}CQYIP3G18~yp238% zm4?p-jW~grvx!D!XdN~P=~=rl zS|<3C(FgHu@4@(`S8tB1Ge+)s_By8mS<8z%kvZ6%U4(#h zD-d^dBa%1l)Gus#;v=^v6)8{0|M;WzfM}8gdN-s)nNd)4#Uwm`;bC-LP73n>>9cOJBDq-lra^G z>k`OC%^O|H>#ZEQmyNdbHS4fZI%ZKha@HS178|*#+e$bRw(dsQmTgGeF8rU6y^+bX z?ij``Vf7~{`x-M&aEk?uTvM)5j^_u?HVmLE{U&mQ7}v=dP{IaaU0(=E=f{z1w`e*I za}qf=Q-q6pwR?1~Ar90Mh?Dzl;TeOmU=0C{tT(f!;OAa__^i1wXuhJ3DdaPwK9W<0 z!rYU{8(X_8ArRrG2QS0bzGLul-_bZRcsa(8y`ZQkVfm>2I6HVT4i0&oyHryK8=iX( zacPe!crieFFv~X?cCCY_61OTJAGI;N6e@t@mhooO3dW3&P`RroAu zqw`5TBsNs%!@2e>J)>ONHGBvknXKTa;bD+^hu4f_(cJ&#}vvZE) zt*nReP48@c(PuaxrN(tkfeg1{_zpI@pXP=)zHSVXedwri^cj4BXF%cIXTzm^HrJJO zHs(PIdN?6a%7E}bwj2=!nF<^2(PGI1jo%lm(-Q$HE=Hm zk35CpITgqoU#ZBq8;Th$#w;0ih{cbiJXZb+-Lv-8*cCtu->HE~re!7(Tk9l8xiRq+U%d14xN zFMAYg=WfK3!V(nZmtp*brp1%`V8VoRD9k^GrL%Tp-MkGbS+)#k*W@#qh9Nv|C>z~o zp7(Dkq=R_xF7K*rZRyK;+IqMjvADU>qZ4g39-UY5#)LS~pjluJZtYX>(Nm%L{X{$b zQWlDzj)voh(n#Dm9F1=db;9YDsql-PgwSqu~#uN`fowe!<(^sPVJbT zznLco3BA_y0NF8d5sy=Tu@mslt^|C``uP4xH1G4LW8wIc+yeP>4)dS@gk>NgtF;>$b!y0yM_ z0&!VS|8FS#86o!SruB^5PT%t2`K)nAO@Mbq4@?~yhmA91u(>b>3-UT6GA>C`PmV*2 zq7;P7@zc>D6y|hM+$W(en|;$q#qoAtULTIr%OkOHd}sJDS&Zv84Z`SGw~g9M9Ex1l z_RSbmMOc(s+q-qu`6Yj4=~*CwexrfDBWC=$DFk-xfvwC~)bsN!~4f$%J8n3G^{HI^p0o7NtS-e>NZ0d{dTVHw-R?EhYcP5QsJ?n z6^r8S^}dPkh@I5AF8I?zI{EU9dtYUvrG;0khWdWvVx@BC7Ie3B4VyxH+Rf#P?s`-o zyu;49-7Mlv)vA>P=dg*zn$C*ZtH0K>a~XF zL+sU6W#bU5^GOgM-j#ka@ID}Mq4kRUm&)2cj&r4IROVy0v`{%Z(jPSNvUxCY49kl6 z50~C|MQO4Px9&G>9Q`K|Mo_erEu~F&uZP;so&Mk5^MfyLz5e%nYNo>U%T1?!C z9GN`vYHFeBq*3wdr3%)##U2)oK);)5k!^~*3et81ZML~al@TW*H{`A@=6Z}v3zk_? zWT&IGa2Ax$^UR1pcJU`N0_njBjM5*0lFWl3C*${A(p?2#?ZigN-_mu_RTSmTAs6$(oPDg)X$d4gH zdkxp~N7D87xE*svG=j=erB?f}*AQ!seZ0mk>LhJW84h$T zbhg~A5WY;oXRXdB0UFnc)7EM|ooa=My3wC3xueLJ3JFAMm`B2_RX02D(YcjX=2On*>Ge%I~!iX0hAt86eWK_Gh-%2u*?1BzF*wU$1voEqN zRV0^W&qfX{*l0F{+v(c$)Vf8MXuZ09$!CP%ng}-qW88vSL463M3mb|7^xK}vAepqT z9roC1TlXSaxy*v>bRKd?x}3U-q2$F%xvXRM@L9%ffxvV_Pp;3RwyPUcT2~Vp;9iPf-HLV%Q z5aBj9Hk~xB0%vI2MxM}m#(hkL2-_M&pur#nAswWVD~Cj`@^dke%G;nnIYp!=@qK&h zllo>d&^Om<#1rv;qPrnqe@j=kx1x~$q^T?!!bc^zrZ7fA1j{s%dBApy+^=1j z|1~oRU-r{z6&?yu7{&zn$mjLxUglnYr{{C1O=_F^puVV2>YK~JWib$6%k%s9Mv)Am z74m6~2b<~AtY}ZfFvQx~yY%I=!!>NJ+AZ>k#y$2q<}Th~LGlB7+F0ik|CP==;TsP2 zo<8H(SRJaXc8fZ!X&bgy^I+g~YKz(wNvB^c2@?9GzIjehTgdl3@y11p5&Sy|+~-oz zv*Vc)eVLi|*NLnSjJQaKXmS^nlQVyvW@qo**Vf)Gi$L$`Gi$Ydcd8@SrR@Up>C^_b z6~No(ftCArIx?ib?|L8K)I!SB$RnRigpeC>;$LW{+?%@xK10YbWljPQxk8l$PGe!Ep!S;#5oF28rVAv{+dXw0T0R$|76$L>-M3EvW8pVnwV(g+O_JXk_mKY0)C<+=I#N4cP z6K`G;Q&*}<%r((8^OD^AlBoIK-us*x2ABrSC>YOL{~DM%XYc?2{=UziGiGLwkH?1r zhdCh&jv^QO)t#LmDl#85lu90)b0xfWRd>gV17uYxDu3YjnNP zCHg%=UyEF#exc3BJ`am069nhX*|FUR0ubx`h0g7Z-mFDp|aB^Yqgl_ z+1FO&5>-x;mGZ1nmd;`IwAAAcfos%QBG~6D0d>dbhe^Ca zsQ&+)@IJ0lEGAQj_XZ1P>=Zlpb`m*9SE>QehnWrsd~>hh!xQ&Em4V9Am>W85L)VzJ zgw9dJX}#Xe>d~pFDbF{kOqyivaPgjWrc0Vx{a>99{1ycQ_dk(sX=51bFnK}ANLCk8 zS0C)uR&Rhe5E)-=l=-16fls!inIYD4K@~$gMXYZ_ZcxdkxM*gpkT=2Lp;^9HxDBz2 z*BdRRGlv|5%T^MO6j#mMgX|uXC-4(?^OKUe_}U{EatsVf0w=}mW;R|n4_FDx3LvWs zVdA__@ZEYt*u4*FZeku;B?z5JI8ucn(^p5T8kmHg7c_<)3VLKJgoR}gF5dyslI^gb zwgOf|@*wg}=#a{gckc~rw;1-S>pa^Yv9RwMtG1-UWG9{wc}T5EvoN{!3tSY7)e=)9 z_#SbvN-c)ry(R@3#uC+ zICTYrlP^PXq8_4yH4v@d46C_ML0V9P(BS?U>=TJXzc7^eg`y-h3R$7?@YE9qT0;&# zad^GD7#o+3(W-#R_yk<5oq|8!nS*~Eorutw1g+z__{OVQe~Tq_f=R^JR(7H8#!kxS zN)kCo9o3q2vu1E$6X1o1>mb@!1*?kv5U<}3N%=ZRRy_mjxH*L}gluk=WQGSZn5M%(cd?0iTJE68K z!`x`rFL0u_3)R=un=)WEYZ$bsq>vOPru9A4gSrUfM!E)1H z2sScOWi@`{2`*zBn{60m0s}Mh!!DBxy=Lbmtri`J4hT@rY^XeFiQR zSvm&g8_5g!ghIMLp>x!yP25e5tO@gOvllUIx7zUnMEk25;6fUPYF=R^BqTY088%z? zBk-xUcp^Ckr{lu#`LH-#8J>u-;eF7}z0;Sg95#;OpPNa2yBQ%VbK5sa*SAs=_yOIc zknIzKj9w9tOKt{x}8d(g)+UjKO$+WFoGoC*YrxvhiG5DP}&i4*j1$498;^A>CCC>+G2Z^#WF; zIm#_6!iCx$_|LcJ7}$mqRm!K=j$-NZ`EU)fX|gU;^uQ+tN#HT0RCpzCKf>fd9Tdhk1dsZ=6mquyl_2QDE=u--g~m75kU8 zXtkmB7)bPf?L5#So;pp8{?NO zn}>gYbfR6rH>V%JJcIcQXOpU^Ppg$cmml`7&tbj7@7Lzw%8`jWz*o_IS`i5xg4eV* z7jSDC4nYz!$OqagAAKYa9)@ly)6gw#2Bb-O+@hR5S62)|)sc-x1zw$Ko+w|v5K_<9 zm%1gzBe1$`G!~a;uvbGXB7tN0M`kj2yH>0daj{?Es2HiM?l<<5fg&Lluhu_@yCh_o zN&%F9y?GYpYsy%dYYmS!q(c`IPp4tb){DEAE^&AU_0iK8L_%O2m}6)zP8-tJi77*a(r?P5rG%v?n5 z5adiQ{&(}_Ybx*?UfTIUfLEtaNQD%gIHFy=&zzEmEz7eFDM`N(*?4*J701wNpN-vA{y3W>9sxh>Q=4Jv48%$ z7OA6iOuRfnFr=NaL-0QJjcdB@c3BEsqTVpI0)k?P;s)txwSn`$-@k-PV(Bpi^e$%? z>jYgJQDto+UUBDp?Y+c5F7JV(Z$Hy2fc6BAVQ=L3U9u5 zRzvw2HcI0iFC$XlA)_=lT7QsmQ}xLaxLjP(Zs66)f>8fg*5lS~&Ec++=7R2VrrOGK zzcCN^=IJO$x%f{sRi^QNuMz3M-nA?VvJUmTb9kF1)^A9HEr0iUh>c+N+GxnD8}T{u zgb#1lFps#)D}aW=xPj>={5}HT725}tYs&-5`n0RSIdX4XyI(`7duS3{wPZ<<#Ccl5 zcwJhB=$D^1O32YgG?&ms?pt4u$d}imo>WXM(UU4{#+>OU-ufN|%Wgr3X^z#@4=59` zfNr}pr2=LWL6v3a#p}mR4!SNXyt-W#hU!T#V%i%uQKTOTxuTYcEt)HUXv9H66mZQ{ z3b6O-i<+t}Dxp6kVZg6`^+N%lDt_082UNWL^wk-71}B>IPMN?d^nEiknH_KaU0SSu znu&Wj5m&ixDh2pQ4{4HoX~i>&R6BYBJG}_z3ueK5)g0aDom>QqnKNL%X`bFO2fn%i z-+y&C-2dRT(TMmcV>XsopUiE-c5DFB|)iyQBhJx$4PwuMg>5l5mXpP9X6J)}{ap zfqkz4feCwnXP$XVCGdZKIFAAngU$5-WmQ)OuiCk=Ik|v&f<9mcC(F>IrWAIyPwG8) z>}y+D>8s@FMCGP7-7he>8Kb>`ynCdEN{Cm0tzRfP@fTAm;QW~im9U?Fa|Ut)tbfU= z@p$*d5WHBO30dtzz2{G@Da8Ba{G-(waIc-Gr&C^ze-STKdE}M7a5qUFP&Q)`zgo(? zdTUca7fT!8FjFbOB_ILUUOT7~_UZTb8k8)rofwMy$NS-z;|cIo0(xj6%y%wOonyXp zKFp4lK}fu%wmOZS|6NrQ`k$Gub8PB;CI9m*e&@a5=Ev3WBYDci3W((rum%MP?0kYu z6@o(h48v#dRx&~FkoteXKQ zZ$3H61ieb!-u>dr_LY)E3Fa&3aFtQjqIQjS;?pB4&!mNd>5_2xca~zeu$BtQ;uK)z z7V2&rk@JO}A{T`2@vlaqjL8e|(+$qj4u5h8UE8?AX$l%clCd%j&0M?!#+17e%RJZw zXM81e@b+N}NNlnmw48g)mrQ177nys_J}MuC?(wfip`7W9@XJlE?k;_6XNLiw5^V-Q zym^}OwqpG{7*lSJ3K*6)AsO$RiN(&E)`OJKWRuxNb7*zo-vBj9aa5H}UmRo{I zdUZpGQh@N>5*+*FFyrmWkxGOOTF!Vjssa>50YPbWDZks9l9FbsZxIbgf$gx6^Box$_X_%xyry#0C}5l&B0;7Ag~!tqlqw z7#93x7dal%UW3-L#W;ng8#3IRBAI{kINk%u#Rc~bov2%M0kf9mtQV12*nkOy`N@SB zP*BuVAW9QTFJSoALkKv!8S=Bs9}4geXICQh;5KAzJcfd)^(}a8PE;l;84O4(i>}2#Cu^rj@=NPkd3r^vU zQ8RF3L@wSKIRne`jW&xTcVsghPOgUJ>@uT+P49?F$+(WyYY=vL zE7GNULnUu8farWd2Mpr*w+ zRCbDiz7Rx8d&vBT(7R!_JjPlMpJDVviPU#UL1P}!o`?r#>_yImiw0SgHkvV^4sVYv z!GDIQ;m4HGxSUyL&~+t5sSEO}888zIFYEU(LN!?{@%e}e_-aHRPG*&p>n>?MzdZLv z)Qw(-$}!JiUj9jqxs1wAG0>BMVHZ9YR^8*KQ*6z=5=HtpW?2dBd;&@5c0*qn@`#^? zkb%osxt2NpbdxY-C>0U#_Kn?)Td8B25?&iMTkkb<3FvPTrTscQ9k)}naVUGe-fIer z>hS|nu+pjTYe)s; z7*mAqeP$qX$QleB^*lz5J#}}zu&E4G7Ag~!jmk)6)msU%`al0JAAV{GrcOMzdJe8cvXOZY%I60` zYx@DpoNMe9^z2`XU}7clDO)gn%wc4a=4M>MOPExA9)*)Gw<~nbE;xe~xrebR|F}V5 z>huo63+0LOMtP*XQl2UAR0b+bt4hyi;YZ@pdm6=5cl>V}hOEtmLT}O)e_+gYA==19 z4w{Nrw~xW4&BZvfdJ!rXuSfa3J(xSa3dNJpw+l!^h|WRhqI1%@DG!tv%2VXvC)(C* z=~(}f2c~^&CJ+R0yCDqyu9&MU-8$hY4@_Olynr?nZRmx(;HY{9^9gEjt-IEm>iGEf# zb2Adscd~2fwR8+R79I10JxOd1Iv1Uj&P{osyu7o@BgQ@==awNQX=`XgZVImN55*tVeoS~y8Gg8VFqnO&>6(CqarpMdAl3QW z=;Hbqt@B=3*SpD_%6UJ2J`|%yryFnatugt2*VV?OKgH6(@T1n0IXFnDFUSK^b}=t7 zq5>%S6F}z_55=BE{jq;ZKP;U-2r+}l=m=kVI8h#tdpf}X?YKWm$(UOEmcHXLZ^}^A ztck-bTcUCH=~%3oF%W@-7o*9>M-0-;Lh6(B0>zNWvX#$`;F~flJMVb=h;g@#?FFh; zQv$40OrAmK1}Bb1#ghs6Vt)t&n}UAtq%ZDN2H^eO;g~%s86I)DdI|(mKF5uRPrn>= zC*hF(Z&aC-)*n3bdy!4|B-VU+d5PNgl$37W=%d};W&X(<>75-@D4_L;JRkANqmeg0 z6*DF#qogPqS!2==M3mF*A@kN~{UrAH?Ds6ij>oXAPfcODz|Kq{3APQ(`pD3};O|S^ zjTd>~h)>Ndts}XcFRhFH+PuI`(ldSS+9Y$6e}JxqdYasoUdV>Ev@aNZ9_A!a}z!e zMUCJSEa*Moz|=3hTG_=>tlC!j==%P!Tuy(`z*FoIIl(qO`>v^~qE1K3swXt#uFxf9 z3dM-W%IHr|v^0}Q9BF|n@0GNUX8ON8*7=OlY!4IH-wLc)H|t~V!~r%ZOUKTuppI{jK8%OA`cjTk*|#I{jHS1fq##6 zyS{@O2o|9nCJY;s|H4KWWj-JjE(=Kg=if>RYT(O!hhC-oNlY2{wS}UtB-T05hu4#E zryxprtuY)u!a0G9`D~p><~Q_TMD`el0f)r{{mCnHwWQpGP=wq+`I0IzN3y)|XqB3L zwZme*&p;Y>qL}QBN%w*O!jd`L<02N*Ul^jlLKi0U9dw+OsGJh`+W3*F^Z9B=>YYFn zZa9;flU?vIf8L5y0_TF%6GEikeK**IX8uX{LUMVblX`_-sosf(_C0?x54B;)` z;bDW{Y(tmS-pouyl@KI#4WA?rNWISIh0f;9MrKp0x`1ty8a)f$}=XhZ| zm~Dd6Zppm*JWF||yfYcNWGgc3M88X~3`tUAIi9>Xga~CWLuKBH`{hAt-!hNjmT}nz zCO$m!C}l`cDn-$1p!qMEG#ihfht5gMO3H(zN1tuPIFk8r zg2swsz&MbZsR~E^8@`?ztw6u&7yNAz``V2TlT>mQy2vdg2Gt`vAg^GK; z^>U;HR{cHYd1_#*ES-W*`V`bw~J&Leq^|Y0hJMna-R|HdF2t`}lx{eULht87r z?7LCsGvJuqZ|KXUw|JW<<};h1kvB=RciT23^9M@wZ<`SE9{nsZ^=-Ld^2?+IuB6vW z+(T#5vFMmQ=)v4vWKK3WtLd%(4!~>65$rn&EauXr$5l=~{Q5ctE0h2iPDnw+MOTre zzfkTtSV%y%w)aS6#%76?#dirmcb7*k)U-tr7JSSV z@?pT1eW97w-Yirx5Ao(hmLCtOKWmN}$)EqM7k4hXhF(j@;JzGf%a1MO=d$>_18;~z z1pHk%G3&C~P6KH-7OyF&P05LU#_dLs^VeAMV>|}DoeEJZ#exqRU3gH{N%_8onQ?!| c%cRHu1FhC|~bpQYW07*qoM6N<$f^mHn`~Uy| diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 63b45e6d81ffb3b867a9e8b8a4e8f0d71192b7a9..78eaec8d06482bc669c92468a36287fee2148be1 100644 GIT binary patch literal 7121 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 c%cRHu1FhC|~bpQYW07*qoM6N<$f^mHn`~Uy| diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 1d205893192b15ecd55a71fd7274e752100c14fd..010c1187c8aba4ab436100cc5a7a33d8e2a188cf 100644 GIT binary patch literal 11383 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 FV1l<0#2f$s literal 10847 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 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 1d205893192b15ecd55a71fd7274e752100c14fd..010c1187c8aba4ab436100cc5a7a33d8e2a188cf 100644 GIT binary patch literal 11383 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 FV1l<0#2f$s literal 10847 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 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 0b2aad424696960b07804e3feb4caa5f14873442..3991b2c251faffecec0408f35fcfd181f11af64f 100644 GIT binary patch literal 16249 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

    tj^w9+5 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 z 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 QqyPW_07*qoM6N<$f-BYitpET3 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 0b2aad424696960b07804e3feb4caa5f14873442..3991b2c251faffecec0408f35fcfd181f11af64f 100644 GIT binary patch literal 16249 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

    tj^w9+5 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 z z*hCaurvY&c?*(`a#Ji0ExnBUBFjhVG*ee$$N)VAtP^*;KdXI z-?BSc^iueB`Iul!#q|7B#$nYK++UX$P-lc})n35TJ*Gk#QFxnDAwD4HrCHRc1YdS> zTjUfvhFX6HW42nEpEgl|x^)3ujW3|?DOeuRZ9Anxd_c@glXL#%_mp9M@MU)g5K{zO zehkK1H}9{{i?wZtd&1nTzraEoqYTOYh;5VLYXiJAsozK8*Y&>w3rRf1ltAps_Mu5z zGwdA@D4O;ZiTv61zUrPIqp<$E zIz^RqXI_yg0IPK*cv+3rJMv)n_^c2wjix@KxghsU+Da?F43?Z(Y)RT8?Wuo2%(yGO z@d#ybkC)igC{KlWc{uf<1+O%0b&g~(B=$0;KpzJO` z*}OE^=^2puok-!7!%`nV=4E#jQzB!dKDq*8E){Yi4-klMOy(Xx(mK5FU$kM4j|X_E zx7wS1OX3>#I7@v3IZGYY)Te{Mhz}i9NZ=+A3bA)1OzxAq5ZxPJAK*pTyS zy9%+wV#duBs82&wNX|y?UTgzXxWYeUk99-=Dgoar!HcG4h6cSpN!5rE7AxMItdG%C zpN5*{)CDp>rkEj!lm~RXfGhfKWBAMvpYdUeU2@;lR|qzubQHYA#+dcdhYDfQ!kQZo zNF+9iR)Ia<#zF@l6hF#Reit{kvhq#;P$IGJq{aKKwF+J)r2x7*M!E4osMyvcQxTl= zUyS;BC3rN!k5pLU-}V1Q)^6E|34)Da4)1T%PS2K#2bd+4LLn|^3zIqo^sx%cxymR( z=^Y*vk5GpvZfX_K^_s-Sqks*1xl0^PlJ_?z9#C(w?kNz;!Z6^GIRzFff^x3$O7O_Y z9lEa9zv~Z{c7B6s&?~eI7ceijb6_zdHieX@zEntEAFyHz8(wN9uyhF;pa{yo#>WJY z0_{QYXI{5-2q@)%--{FUa`XLWf_8FngJN}&%!#JDghIv>*as9VgR-yEz9FV%g3k`M zt5sbr=O?u1f#s)j@6BRCUF@=GZ{TkzGvv%D0kr}VQU~8YR>4{SrF8;6McQ8Y{(Y?c zW41@(m+=M5`6I}jN3h^`ZVwrs=A}n*dpl-8BE(iMnTo*7w{gI1R3-QMim|Czc+2iH zdH%HbMGEI06#N#Jk#x>$r#pr19sIh|qn7Lf2UZD$)DxIXsmy^RRT>+U}0eqBlAh!ivy@xRmOwMWP)96 zY*PmJ1eteY70xBg`NLV-qYeI!j}rJBQUYf!C5V!HCM~iK?)8_ZV8+JCP8 z56rqHbB|q)bEp;YI`iPKUkTKKu^0JOh*}9`F5zR8L0Mm8TtJ)X_;zaJ<@?y$;NRt{ zrE};64fvV4^x_1(Jop<3jMXVpEQ|!=K0{<6BS`?2rSQ*qxfUhjy@AnKeM)&kdV}0M z^@_;aEeGdJz$icvJD2KIr#joigTDbKP#4RX9VVE-DS`}Yw8ATSoiZfnPufk2>x_AC z(6&}Tw)`H>1@X{-$~@vWv3y@0?E15F=*Z6LBa!MfRI$v8?F+#@ApO)CB2)sYW5{5I zf7g$2yF7N81WnUtVF=-iur<(KaDw zo1$WD9x@k+l??lJbqL#?(-=phx zqX#g#eZRE#qz-{2aSk|qKY$bL+OTsc;=$i^CE#X=lq{EID3L%I#_><=f`NGcT`WlA*ed)pe~`Jytwj&avHD>g%Hzn+6*tqvgTI++QgvLQ;7}rO zZkC981EqVe%&Sv136lT7#rL#|tYRz|4`{tO{)2HNKU+ui17&cJKjdD?N68rX;aL4h zItR>Ls40(v!}s}2PYc8aGB%g&#AX=K@?dNb&3c0vsblaExo_GftB{=A7#}=%cNwn; zjRHQqmn-G@!P&RvKB+H~Aa^*9Eo=3o>6kNP@4?Q6H9I#v-){vJg?nvE}z^N)xNN z!P&Qn#ebOvzDkSk1hZqT=K5T#&!;%s&>JA{v}Lmoo~&yQ5im*+$xb3tqoH!2PRHZw{YC2ZDO<{Kw~CM2EF_iLEnW`gEHYGt@r$2+J@&B`-{D~x||xhbvOl4n(T zcREF$eHxCz1K>-eS*oK3zMAJd=%72i)i=^ik&sQp$vN?X8^KZv)sC3L@gIX@|qv;qhxqLOpcWngldGMRCBG|Km9Okcm*pwa#@|b{6TN%V+WjdDp zWu9?sWIn0q5md^coZr!^V%7u$X+|kZ)wBuaK1)3~6pEFYhluv)V>NPLbAC10$+gi- zVGyef?)ke_K;~x(-_GaBy{;wqJc`_VhWa^bgI+^(0@yL|V8_Is2Y&lk1R0yRwq*-A zYI?+a1q235k)%>>g;1G`W$Bjo{uO9dWnM{ptA&MpO(EOEAhY zfGP+A)<#vrW}S3+1C5n0rF@-!9={vapP@12oYV`2_Wny5oPARfnE4;PHr@l?3%RFC zyf^dTH;uckRp>{wW_W5WZ#ohyPmSXQS`xn99tOBsSSG)XGu#thLM z%NlDgmZwtMYh zsMSp>YHM zX}q~uoGP-k$r8!!dP}UF`$=qE3ne!0#f*@j$?x!Q_!;~x+iVug;q5Uxz#h$7_-H0= zNdX_m-m5=*?`li$%s!h5Bx_jYsB>mA|1+L&r$?emM3!+g7pxTONY}o0je0% zSPQ9DETbIK7%c^9f=C%EM$U=n7N}bim={Teax6R-@E+_vJF(B84SJE5wdb=syjRe8 z1+Fq!vJ^qd@?^C_xUf{hlg*X;vJ@kL1!E8k%n;Thhcg_UZ7EP!SZfR0ZlD$l@G$lq z!R$E$*=zW**YsxZ!JWM)HQ;U8dseW|pbdK7+Ve-Fl|jgf8Pp1)_7HX~t#D!~hARt3 z4;GkSEJ%GgN}?8jE#dynm;H`6dk#U@|1Rfz&yoXj340A)VAlnB9`yXtYD%H4 z7;5FP;3$cZqb$0F`x)+c&FcX=4|e`AI)$iDIXcv%EV@A5p#hNdfH&ar|Ev9ee>x~m QqyPW_07*qoM6N<$f-BYitpET3 diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml new file mode 100644 index 00000000..818dc657 --- /dev/null +++ b/app/src/main/res/values-el/strings.xml @@ -0,0 +1,1259 @@ + + + "Σύνδεση" + "Αποστολή σχολίου" + "Απάντηση" + "Ανάρτηση κειμένου" + "Επιλογή Subreddit" + "Ανάρτηση συνδέσμου" + "Ανάρτηση εικόνας" + "Ανάρτηση βίντεο" + "Κανόνες" + "Subreddits" + "Επεξεργασία ανάρτησης" + "Επεξεργασία σχολίου" + "Εισερχόμενα" + "Ρυθμίσεις" + "Αποθηκεύτηκε" + "Δημιουργία Multireddit" + "Επιλογή Subreddit" + "Προσαρμοσμένα θέματα" + "Προσαρμογή προσαρμοσμένου θέματος" + "Δημιουργία θέματος" + "Προεπισκόπηση θέματος" + "Επεξεργασία Multireddit" + "Επιλογή Subreddit" + "Αναφορά" + "Εικόνα %1$d/%2$d" + "Βίντεο %1$d/%2$d" + "Αποστολή προσωπικού μηνύματος" + "Εικόνα %1$d/%2$d" + "Gif %1$d/%2$d" + "Βίντεο %1$d/%2$d" + "Άνοιγμα συρταριού πλοήγησης" + "Κλείσιμο συρταριού πλοήγησης" + "Λήψη" + "Ανανέωση" + "Προσθήκη σχολίου" + "Αποθήκευση ανάρτησης" + "Εμφάνιση γονεϊκής αναδημοσίευσης" + "Αναζήτηση" + "Εκκίνηση Lazy Mode" + "Σταμάτημα Lazy Mode" + "Αποστολή" + "Ταξινόμηση" + "Απόκρυψη ανάρτησης" + "Εμφάνιση ανάρτησης" + "Επεξεργασία ανάρτησης" + "Διαγραφή ανάρτησης" + "Επισήμανση NSFW" + "Αφαίρεση επισήμανσης NSFW" + "Επισήμανση Spoiler" + "Αφαίρεση επισήμανσης Spoiler" + "Επεξεργασία ετικέτας" + "Αλλαγή διάταξης ανάρτησης" + "Αποθήκευση" + "Επεξεργασία MultiReddit" + "Διαγραφή Multireddit" + "Κοινή χρήση" + "Προεπισκόπηση" + "Αναφορά" + "Προβολή διαγραμμένου" + "Ορισμός ως ταπετσαρία" + "Αποστολή προσωπικού μηνύματος" + "Σφάλμα κατά την ανάλυση της απόκρισης JSON" + "Σφάλμα κατά την ανάκτηση token" + "Κάτι πήγε στραβά. Δοκιμάστε αργότερα." + "Η πρόσβαση δεν επιτρέπεται" + "Σφάλμα κατά την ανάλυση πληροφοριών χρήστη" + "Σφάλμα κατα το άνοιγμα System's WebView" + "Σφάλμα κατά τη φόρτωση της εικόνας. Πατήστε για επανάληψη." + "Σφάλμα κατά τη φόρτωση αναρτήσεων. Πατήστε για επανάληψη." + "Σφάλμα κατά τη φόρτωση αναρτήσεων." + "Σφάλμα κατά τη φόρτωση της ανάρτησης" + "Σφάλμα κατα την αναζήτηση subreddit. Πατήστε για επανάληψη." + "Σφάλμα κατα την αναζήτηση χρηστών. Πατήστε για επανάληψη." + "Δεν βρέθηκαν αναρτήσεις" + "Δεν βρέθηκαν σχόλια" + "Δεν βρέθηκαν subreddit" + "Δεν βρέθηκαν χρήστες" + "Δεν βρέθηκαν Multireddit" + "Δεν υπάρχει άδεια αποθήκευσης για αποθήκευση αυτού του αρχείου" + "Σφάλμα κατά τη φόρτωση σχολίων. Πατήστε για επανάληψη" + "Επανάληψη προσπάθειας" + "Σχόλια" + "Κανένα σχόλιο μέχρι τώρα. Γιατί δεν γράφετε ένα εσείς;" + "Η ψηφοφορία απέτυχε" + "Σφάλμα κατα την ανανέωση της ανάρτησης" + "Σφάλμα κατα το φόρτωμα των μηνυμάτων. Πατήστε για επανάληψη." + "Κενό" + "NSFW" + "Κάρμα: %1$,d" + "Κάρμα: +%1$,d (%2$d + %3$d)" + "Cake day: +%1$s" + "Από:" + "Προφίλ" + "Εγγραφές" + "Multireddit" + "Εισερχόμενα" + "Ψηφίστηκε" + "Καταψηφίστηκε" + "Κρύφτηκε" + "Αποθηκεύτηκε" + "Επιχρυσωμένο" + "Ρυθμήσεις" + "Εγγραφές: %1$,d" + "Ενεργοί: %1$,d" + "Δεν είναι δυνατή η ανάκτηση πληροφοριών του subreddit" + "Δεν είναι δυνατή η ανάκτηση πληροφοριών χρήστη" + "Δεν είναι δυνατή η ανάκτηση της πλευρικής μπάρας" + "Δεν είναι δυνατή η ανάκτηση των πληροφοριών multireddit" + "Εγγραφή" + "Απεγγραφή" + "Εγγεγραμμένος" + "Η εγγραφή απέτυχε" + "Απογεγραμμένος" + "Η απεγγραφή απέτυχε" + "Ακολούθηση " + "Κατάργηση παρακολούθησης" + "Παρακολούθηση" + "Η παρακολούθηση απέτυχε" + "Καταργήθηκε η παρακολούθηση" + "Η κατάργηση παρακολούθησης απέτυχε" + "Εικόνα Μπάνερ Subreddit" + "Infinity" + "Αναζήτηση" + "Καμία ανάρτηση" + "Το Lazy Mode ξεκινάει σε %1$.1fs" + "Το Lazy Mode σταμάτησε" + "Οι σκέψεις σου εδώ" + "Που είναι οι σκεψεις σου" + "Αποστολή" + "Το σχόλιο απεστάλη" + "Αποτυχία αποστολής σχολίου" + "Χρήστης" + "Θέμα ( Μέχρι 100 χαρακτήρες)" + "Μήνυμα" + "Αποτυχία αποστολής μηνύματος" + "Αποτυχία λήψης μηνύματος" + "Σε ποιόν θέλεις να στείλεις αυτό το μήνυμα;" + "Το μήνυμα πρέπει να έχει θέμα" + "Πρέπει να πείς στο παραλήπτη κάτι" + "Αποστολή" + "Το μήνυμα απεστάλη" + "Αποτυχία αποστολής μηνύματος" + "Παρακαλώ διάλεξε πρώτα subreddit" + "Η ανάρτηση χρειάζεται έναν καλό τίτλο" + "Που είναι ο σύνδεσμος;" + "Παρακαλώ διάλεξε πρώτα μια εικόνα" + "Δημοσίευση" + "Αποτυχία δημοσίευσης" + "Αποτυχία επεξεργασίας εικόνας" + "Αποτυχία επεξεργασίας βίντεο" + "Η λήψη ξεκίνησε. Έλεγξε την ειδοποίηση για την προοδο." + "Λήψη περισσότερων σχολίων" + "Η λήψη απέτυχε. Πατήστε για επανάληψη." + "Λήψη" + "Τίτλος" + "Περιεχόμενο" + "Διαλέξτε subreddit" + "Κανόνες" + "Σύνδεσμος" + "Subreddit" + "Χρήστες" + "Multireddit" + "Κείμενο" + "Σύνδεσμος" + "Εικόνα" + "Βίντεο" + "Διαλέξτε μια εικόνα" + "Διαλέξτε ξανά" + "Αποτυχία λήψης εικόνας" + "Αποτυχία λήψης βίντεο" + "Δεν βρέθηκε εφαρμογή κάμερας" + "Αποτυχία δημιουργίας προσωρινού αρχείου" + "Επεξεργασία βίντεο. Παρακαλώ περιμένετε." + "Επεξεργασία εικόνας. Παρακαλώ περιμένετε" + "Επεξεργασία κεινούμενης εικόνας. Παρακαλώ περιμένετε." + "Ετικέτα" + "Spoiler" + "Χωρίς ετικέτα" + "Σφάλμα στη λήψη ετικετών. +Πατήστε για να δοκιμάσετε ξανά." + "Χωρίς κανόνες" + "Σφάλμα λήψης κανόνων. Πατήστε για να δοκιμάσετε ξανά." + "Σφάλμα στη λήψη κανόνων" + "Αναζήτηση σε" + "Όλα τα subreddit" + "Καλύτερα" + "Hot" + "Νεα" + "Τυχαία" + "Ανερχόμενα" + "Κορυφαία" + "Αμφιλεγόμενα" + "Σχετικότητα" + "Σχόλια" + "Δραστηριότητα" + "Αυτοπεποίθηση" + "Παλαιότητα" + "QA" + "Live" + "Ώρα" + "Μέρα" + "Εβδομάδα" + "Μήνα" + "Έτος" + "Ανεξαρτήτως χρόνου" + "Δεν υπάρχει εφαρμογή διαμοιρασμού" + "Αρχειοθετημένη ανάρτηση. Μη δυνατότητα ψήφου." + "Αρχειοθετημένη ανάρτηση. Μη δυνατότητα σχολιασμού." + "Αρχειοθετημένη ανάρτηση. Μη δυνατότητα απάντησης." + "Κλειδωμένη ανάρτηση. Μη δυνατότητα σχολιασμού." + "Κλειδωμένη ανάρτηση. Μη δυνατότητα απάντησης." + "ΚΕΙΜΕΝΟ" + "ΣΥΝΔΕΣΜΟΣ" + "ΕΙΚΟΝΑ" + "ΒΙΝΤΕΟ" + "GIF" + "ΓΚΑΛΕΡΙ" + "Καλύτερα" + "Αναζήτηση" + "Ανάρτηση Βίντεο" + "Ανάρτηση Εικόνας" + "Παρακαλώ περιμένετε" + "Προσθήκη λογαριασμού" + "Ανώνυμα" + "Έξοδος" + "Πατήστε εδώ για να συνδεθείτε" + "Πρέπει να συνδεθείτε πρώτα" + "Η ανάρτηση αποθηκεύτηκε" + "Δεν μπόρεσε να αποθηκευτεί η ανάρτηση" + "Η ανάρτηση δεν αποθηκεύτηκε" + "Αδυναμία διαγραφής αποθήκευσης ανάρτησης" + "Η ανάρτηση κρύφτηκε" + "Αδυναμία απόκρυψης ανάρτησης" + "Η ανάρτηση δεν είναι κρυμμένη" + "Αποτυχία σήμανσης ως αγαπημένο" + "Αποτυχία σήμανσης ως μη αγαπημένο" + "Αδυναμία επανεμφάνισης ανάρτησης" + "Διαγραφή αυτής της ανάρτησης" + "Διαγραφή αυτού του σχολίου" + "Είστε σίγουρος/η?" + "Επεξεργασία" + "Διαγραφή" + "Δες το διαγραμμένο σχόλιο" + "Λήψη διαγραμμένου σχολίου" + "Δεν μπόρεσε να βρεθεί το διαγραμμένο σχόλιο" + "Λήψη διαγραμμένης ανάρτησης" + "Δεν μπόρεσε να βρεθεί η διαγραμμένη ανάρτηση" + "Άκυρο" + "ΟΚ" + "Επιτυχής επεξεργασία" + "Επιτυχής διαγραφή" + "Αποτυχία διαγραφής" + "Επισήμανση NSFW επιτυχής" + "Η επισήμανση ως NSFW απέτυχε" + "Αφαίρεση επισήμανσης NSFW επιτυχώς" + "Η αφαίρεση επισήμανσης NSFW απέτυχε" + "Επισήμανση spoiler επιτυχής" + "Η επισήμανση ως spoiler απέτυχε" + "Αφαίρεση επισήμανσης spoiler επιτυχώς" + "Η αφαίρεση επισήμανσης spoiler απέτυχε" + "Ενημέρωση flair επιτυχής" + "Η ενημέρωση του flair απέτυχε" + "Επεξεργασία Σήμανσης" + "Να επιτρέπονται μόνο λιγότεροι από 64 χαρακτήρες" + "Κάντε κλικ εδώ για να περιηγηθείτε σε όλα τα σχόλια" + "Λογαριασμός" + "Νέο Μήνυμα" + "Subreddit" + "Βραβείο" + "%1$d Νέα Μηνύματα" + "Λογαριασμός" + "Ανάρτηση" + "Προτιμήσεις" + "Άλλαξε ο λογαριασμός. Όλες οι άλλες σελίδες χάθηκαν" + "Ειδοποίηση" + "Ενεργοποίηση ειδοποιήσεων" + "Διάστημα Ελέγχου για Ειδοποιήσεις" + "Θέμα" + "Amoled σκούρο" + "Διεπαφή" + "Χειρονομίες & Κουμπιά" + "Αποθήκευση Θέσης Κύλισης στην ΑΡΧΙΚΗ" + "Περιήγηση νέων αναρτήσεων μετά την ανανέωση στην ΑΡΧΙΚΗ (Αρχική Σελίδα, Τύπος Ταξινόμησης: Καλύτερα)" + "Βίντεο" + "Αυτόματη αναπαραγωγή βίντεο" + "Σίγαση αυτόματα αναπαραγώμενων βίντεο" + "Αυτόματη αναπαραγωγή NSFW βίντεο" + "Ποσοστό Ορατής Περιοχής Βίντεο για Αυτόματη Αναπαραγωγή (Κάθετος)" + "Αυτόματη αναπαραγωγή των βίντεο όταν το %1$d%% είναι ορατό" + "Ποσοστό Ορατής Περιοχής Βίντεο για Αυτόματη Αναπαραγωγή (Οριζόντιος)" + "Αυτόματη αναπαραγωγή των βίντεο όταν το %1$d%% είναι ορατό" + "Καθηλωτική Διεπαφή" + "Δεν Εφαρμόζεται στη Σελίδα Όλα" + "Αγνόηση Μπάρας Πλοήγησης στην Καθηλωτική Διεπαφή" + "Αποτρέπει την Κάτω Μπάρα Πλοήγησης να έχει Έξτρα Μέγεθος" + "Παραμετροποίηση Καρτελών στην Κύρια Σελίδα" + "Ενεργοποίηση Κάτω Πλοήγησης" + "Ανάρτηση και Σχόλια" + "Κουμπιά Ψήφου στα Δεξιά" + "Περιήγηση στα σχόλια με τα κουμπιά έντασης" + "Περιήγηση στις αναρτήσεις με τα κουμπιά έντασης" + "Σίγαση βίντεο" + "Σίγαση NSFW βίντεο" + "Αύτοματη προσπάθεια προσπέλασης στο Redgifs αν τα Βίντεο στο Gfycat έχουν αφαιρεθεί." + "Αγνόηση Μπάρας Πλοήγησης κατά την Αναπαραγωγή Βίντεο" + "Αποτρέπει τα Χειριστήρια του Βίντεο να έχουν έξτρα περιθώριο" + "Επιβεβαίωση για Έξοδο" + "Σχόλιο" + "Εμφάνιση των Καλύτερων σχολίων Πρώτα" + "Εμφάνιση Διαχωριστικού Σχολίων" + "Κλικ για Εμφάνιση/Απόκρυψη Εργαλειοθήκης Σχολίων" + "Πλήρης Κατάρρευση Σχολίου" + "Εργαλειοθήκη Σχολίων Κρυφή από Προεπιλογή" + "Εμφάνιση Απόλυτου Αριθμού Ψήφων" + "Εμφάνιση Χρόνου που Παρήλθε στις Αναρτήσεις και Σχόλια" + "Μορφή Ώρας" + "Ανάρτηση" + "Προεπιλεγμένη Διάταξη Ανάρτησης" + "Εμφάνιση Διαχωριστικού" + "Εμφάνιση μικρογραφίας στα αριστερά" + "Εναλλαγή Αγγίγματος και Παρατεταμένου Αγγίγματος στα Σχόλια" + "Σύρετε Δεξιά για να Πάτε Πίσω" + "Δεν Εφαρμόζεται Στην Σελίδα Όλα" + "Κουμπί Κλειδώματος Άλματος στο Επόμενο Σχόλιο Άνω Επιπέδου" + "Κλείδωμα Κάτω Μπάρας Πλοήγησης" + "Σύρετε προς τα Πάνω για Απόκρυψη Κουμπιού Άλμα προς το Σχόλιο Άνω Επιπέδου" + "Διάστημα Λειτουργίας Τεμπέλη" + "Γραμματοσειρά" + "Προεπισκόπηση Γραμματοσειράς" + "Γραμματοσειρά" + "Τίτλος" + "Περιεχόμενο" + "Οικογένεια Γραμματοσειράς" + "Γραμματοσειρά Τίτλου" + "Γραμματοσειρά Περιεχομένου" + "Μέγεθος Γραμματοσειράς" + "Μέγεθος Γραμματοσειράς Τίτλου" + "Μέγεθος Γραμματοσειράς Περιεχομένου" + "Ενεργοποίηση NSFW" + "Θόλωση Εικόνων NSFW" + "Θόλωση Εικόνων Spoiler" + "Σχετικά" + "Αναγνώριση" + "Εύσημα" + "Προσκήνιο Εικονιδίου" + "Διάνυσμα Τεχνολογίας δημιουργήθηκε από freepik - www.freepik.com" + "Παρασκήνιο Εικονιδίου" + "Διάνυσμα Παρασκηνίου δημιουργήθηκε από freepik - www.freepik.com" + "Σφάλμα Εικόνας" + "Διάνυσμα Τεχνολογίας δημιουργήθηκε από freepik - www.freepik.com" + "Εικονίδιο Επιχρυσωμένο" + "Εικονίδιο έγινε από τον Freepik από www.flaticon.com" + "Εικονίδιο Αναδημοσίευσης" + "Εικονίδιο έγινε από τον Freepik από www.flaticon.com" + "Εικονίδιο Thumbtack" + "Εικονίδιο έγινε από τον Freepik από www.flaticon.com" + "Εικονίδιο Ρουκέτας" + "Εικονίδιο έγινε από τον Freepik από www.flaticon.com" + "Εικονίδια Material" + "Ανοιχτού Κώδικα" + "Βάλτε το στα αγαπημένα στο GitHub αν σας αρέσει η εφαρμογή" + "Βαθμολογήστε στο Google Play" + "Βαθμολογήστε μέ με 5 αστέρια και θα χαρώ πολύ" + "Email" + "docilealligator.app@gmail.com" + "Λογαριασμός Reddit" + "u/Hostilenemy" + "Subreddit" + "r/Infinity_For_Reddit" + "Κοινοποίηση" + "Κοινοποιήστε την εφαρμογή για να τη χαρούν κι άλλα άτομα" + "Infinity Για το Reddit" + "Έκδοση %s" + "Παραμετροποίηση" + "Φωτεινό Θέμα" + "Σκοτεινό Θέμα" + "Θέμα Amoled" + "Διαχείριση Θεμάτων" + "Προχωρημένα" + "Διαγραφή Όλων των Subreddits στη Βάση Δεδομένων" + "Διαγραφή Όλων των Χρηστών από την Βάση Δεδομένων" + "Διαγραφή Όλων των Τύπων Ταξινόμησης στη Βάση Δεδομένων" + "Διαγραφή Όλων των Διατάξεων Ανάρτησης στη Βάση Δεδομένων" + "Διαγραφή Όλων των Θεμάτων στη Βάση Δεδομένων" + "Διαγραφή Όλων των Θέσεων Κύλισης της Κεντρικής Σελίδας στη Βάση Δεδομένων" + "Επαναφορά Όλων των Ρυθμίσεων" + "Καρτέλα 1" + "Καρτέλα 2" + "Καρτέλα 3" + "Τίτλος" + "Τύπος" + "Όνομα Subreddit (Χωρίς πρόθεμα r/)" + "Διαδρομή Multireddit +(/user/yourusername/m/yourmultiredditname) (μόνο πεζοί χαρακτήρες)" + "Όνομα χρήστη (Χωρίς πρόθεμα r/)" + "Δεν υπάρχουν λειτουργίες προγραμματιστή εδώ" + "Δεν είναι δυνατή η απόκτηση του συνδέσμου" + "Αποχώρηση;" + "Η ανάρτηση θα αναρτηθεί ακόμα και αν αποχωρήσετε από εδώ. " + "Η ανάρτηση μπορεί και πάλι να αναρτηθεί ακόμα και αν αποχωρήσετε από εδώ." + "Το σχόλιο μπορεί και πάλι να αναρτηθεί ακόμα και αν αποχωρήσετε από εδώ." + "Απόρριψη;" + "Το πρόχειρο ΔΕΝ θα αποθηκευτεί." + "Ναι" + "Όχι" + "Δεν λήφθηκαν δεδομένα" + "Δεν λήφθηκε διαδρομή εικονας" + "Δε βρέθηκε διαδρομή βίντεο" + "Αδυναμία διαχείρισης αιτήματος κοινοποίησης" + "Κοινοποίηση" + "Δε βρέθηκε πάροχος Email" + "Δεν υπάρχει διαθέσιμη εφαρμογή" + "Το σχόλιο αποθηκεύτηκε" + "Αδυναμία αποθήκευσης σχολίου" + "Αφαιρέθηκε η αποθήκευση σχολίου" + "Αδύνατο να γίνει αφαίρεση αποθήκευσης σχολίου" + "Αγαπημένα" + "Ολα" + "Διάταξη Καρτών" + "Συμπαγής Διαταξη" + "Μόλις Τώρα" + "1 Λεπτό" + "%1$d Λεπτά" + "1 Ώρα" + "%1$d Ώρες" + "Χθες" + "%1$d Μέρες" + "1 Μήνας" + "%1$d Μήνες" + "1 Χρόνος" + "%1$d Χρόνια" + "Αδυναμία απόκτησης δεδομένων multireddit" + "Αδυναμία συγχρονισμού multireddits" + "Αδυναμία συγχρονισμού συνδρομών" + "Ρίξτε μια ματιά στο Infinity για το Reddit, ένας φοβερός πελάτης Reddit! +https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit" + "Αδυναμία απόκτησης ονόματος subreddit" + "Κοινοποίηση Συνδέσμου Ανάρτησης" + "Κοινοποίηση Συνδέσμου Εικόνας" + "Κοινοποίηση Συνδέσμου Gif" + "Κοινοποίηση Συνδέσμου Βίντεο" + "Κοινοποίηση Συνδέσμου" + "Αντιγραφή Συνδέσμου Ανάρτησης" + "Αντιγραφή Συνδέσμου Εικόνας" + "Αντιγραφή Συνδέσμου Gif" + "Αντιγραφή Συνδέσμου Βίντεο" + "Αντιγραφή Συνδέσμου" + "Αντιγράφηκε" + "Αδυναμία αντιγραφής συνδέσμου" + "Αντιγραφή" + "Αντιγραφή Όλων" + "Αντιγραφή Markdown" + "Αντιγραφή Ακατέργαστου Κειμένου " + "Αντιγραφή Όλων των Markdown" + "Αντιγραφή όλου του ακατέργαστου κειμένου" + "Έξοδος;" + "Ανοιχτό Θέμα" + "Σκοτεινό Θέμα" + "Όνομα ( Μέχρι 50 Χαρακτήρες)" + "Περιγραφή" + "Ιδιωτικό" + "Που είναι το όνομα;" + "Δεν είναι δυνατή η δημιουργία αυτού του multireddit" + "Αυτό το multireddit υπάρχει ήδη" + "Δεν είναι δυνατή η επεξεργασία αυτού του multireddit" + "Διαγράφηκε επιτυχώς" + "Η διαγραφή απέτυχε" + "Είστε σίγουρος;" + "Ενεργοποίηση NSFW" + "Απενεργοποίηση NSFW" + "Αδυναμία αποθήκευσης της εικόνας" + "Αδυναμία αποθήκευσης gif" + "Αδυναμία πρόσβασης αποθηκευτικού χώρου εφαρμογής" + "Η εικόνα αποθηκεύεται. Παρακαλώ περιμένετε." + "Το gif αποθηκεύεται. Παρακαλώ περιμένετε." + "Άγγιξε για αλλαγή ονόματος αυτού του θέματος." + "Ορισμός ως Φωτεινό Θέμα" + "Ορισμός ως Σκοτεινό Θέμα" + "Ορισμός ως θέμα Amoled" + "Κύριο Χρώμα" + "Εφαρμόστηκε σε: Γραμμή Εργαλείων" + "Κύριο Χρώμα Σκοτεινό" + "Εφαρμόστηκε σε: Μπάρα Κατάστασης" + "Έμφαση Χρώματος" + "Εφαρμόστηκε σε: Μπάρα Προόδου, κτλ" + "Χρώμα Κυρίως Ανοιχτού Θέματος" + "Εφαρμόστηκε σε: παρασκήνιο του Αιωρούμενου Κουμπιού Ενέργειας και Κουμπί" + "Χρώμα Κυρίως Κείμενου" + "Εφαρμόστηκε σε: Κύριο Κείμενο" + "Χρώμα Δευτερεύοντος Κειμένου" + "Εφαρμόστηκε σε: Δευτερεύον Κείμενο" + "Χρώμα Τίτλου Ανάρτησης" + "Εφαρμόστηκε σε: Τίτλος Ανάρτησης" + "Χρώμα Περιεχομένου Ανάρτησης" + "Εφαρμόστηκε σε: Περιεχόμενο ανάρτησης" + "Χρώμα Σχολίου" + "Εφαρμόστηκε σε: Σχόλιο" + "Χρώμα Κειμένου Κουμπιού" + "Εφαρμόστηκε σε: Κείμενο σε κουμπί" + "Χρώμα Κειμένου Τσιπ" + "Εφαρμόστηκε σε: Κουμπί Εγγραφής" + "Χρώμα Συνδέσμου" + "Εφαρμόστηκε σε: URL" + "Χρώμα Κειμένου Ληφθέντος Μηνύματος" + "Εφαρμόστηκε σε: Ληφθέντα Προσωπικά Μηνύματα" + "Χρώμα Κειμένου Απεσταλμένου Μηνύματος" + "Εφαρμόστηκε σε: Απεσταλμένα Προσωπικά Μηνύματα" + "Χρώμα Παρασκηνίου" + "Εφαρμόστηκε σε: Παρασκήνιο κάθε σελίδας και συρτάρι πλοήγησης" + "Χρώμα Παρασκηνίου Προβολής Κάρτας" + "Εφαρμόστηκε σε: Παρασκήνιο ανάρτησης και μηνύματος" + "Χρώμα Παρασκηνίου Σχολίου" + "Εφαρμόστηκε σε: Παρασκήνιο σχολίου" + "Χρώμα Παρασκηνίου Πλήρως Συμπτυγμένου Σχολίου" + "Εφαρμόστηκε σε: Παρασκήνιο πλήρως συμπτυγμένων σχολίων" + "Χρώμα Παρασκηνίου Βραβευμένου Σχολίου" + "Εφαρμόστηκε σε: Παρασκήνιο βραβευμένων σχολίων" + "Χρώμα Παρασκηνίου Ληφθέντος Σχολίου" + "Εφαρμόστηκε σε: Παρασκήνιο ληφθέντων προσωπικών μηνυμάτων" + "Χρώμα Παρασκηνίου Απεσταλμένου Μηνύματος" + "Εφαρμόστηκε σε: Παρασκήνιο απεσταλμένων προσωπικών μηνυμάτων" + "Χρώμα Κάτω Μπάρας Πλοήγησης" + "Εφαρμόστηκε σε: Κάτω μπάρα πλοήγησης" + "Χρώμα Κυρίου Εικονιδίου" + "Εφαρμόστηκε σε: Εικονίδια συρταριού πλοήγησης." + "Χρώμα Εικονιδίου Κάτω Μπάρας Πλοήγησης" + "Εφαρμόστηκε σε: Εικονίδια στην κάτω μπάρα πλοήγησης" + "Χρώμα πληροφοριών και Εικονιδίου Ανάρτησης" + "Εφαρμόστηκε σε: Εικονίδια, σκορ και αριθμός σχολίων στις αναρτήσεις" + "Χρώμα Πληροφοριών και Εικονιδίου Σχολίου" + "Εφαρμόστηκε σε: Εικονίδια και σκορ στα σχόλια" + "Χρώμα Εικονιδίου Αιωρούμενου Κουμπιού Ενέργειας" + "Εφαρμόστηκε σε: Εικονίδιο αιωρούμενου κουμπιού ενέργειας" + "Χρώμα Εικονιδίου Αποστολής Μηνύματος" + "Εφαρμόστηκε σε: εικονίδιο αποστολής προσωπικού μηνύματος" + "Χρώμα Εικονιδίου και Κυρίως Κείμενου Γραμμής Εργαλείων" + "Εφαρμόστηκε σε: Κύρια κείμενα και εικονίδια στην γραμμή εργαλείων" + "Χρώμα Δευτερεύοντος Κειμένου στην Γραμμή Εργαλείων" + "Εφαρμόστηκε σε: Δευτερεύοντα κείμενα στις γραμμές εργαλείων" + "Χρώμα Παρασκηνίου Κυκλικής Μπάρας Προόδου" + "Εφαρμόστηκε σε: Παρασκήνιο της κυκλικής Μπάρας προόδου" + "Χρώμα Παρασκηνίου σε Διάταξη Καρτέλας στην Εκτεταμένη Γραμμή εργαλείων" + "Εφαρμόστηκε σε: Παρασκήνιο διάταξης καρτέλας (εκτεταμένη γραμμή εργαλείων)" + "Χρώμα Κείμενου σε Διάταξη Καρτέλας στην Εκτεταμένη Γραμμή εργαλείων" + "Εφαρμόστηκε σε: Χρώμα κείμενου διάταξης καρτέλας (εκτεταμένη γραμμή εργαλείων)" + "Χρώμα Ένδειξης Καρτέλας στην Διάταξη Καρτέλας στην Εκτεταμένη Γραμμή εργαλείων" + "Εφαρμόστηκε σε: Χρώμα ένδειξης καρτέλας στην διάταξη καρτέλας ( εκτεταμένη γραμμή εργαλείων)" + "Χρώμα Παρασκηνίου στην Διάταξη Καρτέλας στην Συμπτυγμένη Γραμμή εργαλείων" + "Εφαρμόστηκε σε: Παρασκήνιο διάταξης καρτέλας (συμπτυγμένη γραμμή εργαλείων)" + "Χρώμα Κειμένου σε Διάταξη Καρτέλας στην Συμπτυγμένη Γραμμή Εργαλείων" + "Εφαρμόστηκε σε: Χρώμα κειμένου σε διάταξη καρτέλας (συμπτυγμένη γραμμή εργαλείων)" + "Χρώμα Ένδειξης Καρτέλας σε Διάταξη Καρτέλας στην Συμπτυγμένη Γραμμή Εργαλείων" + "Εφαρμόστηκε σε: Χρώμα ένδειξης καρτέλας σε διάταξη καρτέλας (συμπτυγμένη γραμμή εργαλείων)" + "Χρώμα Θετικής Ψήφου" + "Εφαρμόστηκε σε: Κουμπιά ψήφου και βαθμοί (ψηφίστηκε θετικά)" + "Χρώμα Αρνητικής Ψήφου" + "Εφαρμόστηκε σε: Κουμπιά ψήφου και βαθμοί (ψηφίστηκε αρνητικά)" + "Χρώμα Παρασκηνίου Τύπου Ανάρτησης" + "Εφαρμόστηκε σε: Παρασκήνιο τύπου ανάρτησης (ΕΙΚΌΝΑ, ΚΕΊΜΕΝΟ, ΒΊΝΤΕΟ, GIF, ΣΎΝΔΕΣΜΟΣ)" + "Χρώμα Κειμένου Τύπου Ανάρτησης" + "Εφαρμόστηκε σε: Χρώμα κειμένου τύπου ανάρτησης (ΕΙΚΌΝΑ, ΚΕΊΜΕΝΟ, ΒΊΝΤΕΟ, GIF, ΣΎΝΔΕΣΜΟΣ)" + "Χρώμα Παρασκηνίου Σπόιλερ" + "Εφαρμόστηκε σε: Παρασκήνιο της ετικέτας σπόιλερ" + "Χρώμα Κειμένου Σπόιλερ" + "Εφαρμόστηκε σε: Χρώμα κείμενου της ετικέτας σπόιλερ" + "Χρώμα Παρασκηνίου NSFW" + "Εφαρμόστηκε σε: Παρασκήνιο της ετικέτας NSFW" + "Χρώμα κείμενου NSFW" + "Εφαρμόστηκε σε: Χρώμα κειμένου της ετικέτας NSFW" + "Χρώμα Παρασκηνίου Σήμανσης" + "Εφαρμόστηκε σε: Παρασκήνιο της ετικέτας σήμανσης" + "Χρώμα Κειμένου Σήμανσης" + "Εφαρμόστηκε σε: Χρώμα κειμένου της ετικέτας σήμανσης" + "Χρώμα Παρασκηνίου Βραβείων" + "Εφαρμόστηκε σε: Παρασκήνιο της ετικέτας βραβείων" + "Χρώμα Κειμένου Βραβείων" + "Εφαρμόστηκε σε: Χρώμα κειμένου ετικέτας βραβείων" + "Αρχειοθετημένο Χρώμα Εικονιδίου" + "Εφαρμόστηκε σε: Εικονίδιο αρχειοθέτησης" + "Χρώμα Εικονιδίου Κλειδωμένου" + "Εφαρμόστηκε σε: Εικονίδιο Κλειδωμένο" + "Χρώμα Εικονιδίου Αναδημοσίευσης" + "Εφαρμόστηκε σε: Εικονίδιο Αναδημοσίευσης" + "Χρώμα Εικονιδίου Καρφιτσωμένης Ανάρτησης" + "Εφαρμόστηκε σε: Εικονίδιο Καρφιτσωμένης Ανάρτησης" + "Έγινε εγγραφή" + "Εφαρμόστηκε σε: κουμπί απεγγραφής" + "Έγινε απεγγραφή" + "Εφαρμόστηκε σε: Κουμπί Εγγραφής" + "Χρώμα ονόματος χρήστη" + "Εφαρμόστηκε σε: Όνομα χρήστη" + "Χρώμα Subreddit" + "Εφαρμόστηκε σε: Όνομα Subreddit" + "Χρώμα Σήμανσης Συντάκτη" + "Εφαρμόστηκε σε: Σήμανση συντάκτη στα σχόλια" + "Καταχωρητής" + "Εφαρμόστηκε σε: Καταχωρητής στα σχόλια" + "Συντονιστής" + "Εφαρμόστηκε σε: Συντονιστής στα σχόλια" + "Χρώμα Παρασκηνίου Νήματος Μονού Σχολίου" + "Εφαρμόστηκε σε: Μονό Σχόλιο" + "Χρώμα Παρασκηνίου Μη Αναγνωσμένου Μηνύματος" + "Εφαρμόστηκε σε: Χρώμα Παρασκηνίου Μη Αναγνωσμένου Μηνύματος" + "Χρώμα Διαχωριστή" + "Εφαρμόστηκε σε: Διαχωριστικό Σχολίου, Διαχωριστικά σε σελίδες για καταχώρηση αναρτήσεων κτλ." + "Χρώμα Κουμπιού Μη Διαθέσιμης Ψήφου και Απάντησης" + "Εφαρμόστηκε σε: Κουμπιά ψήφου και απάντησης (Μη διαθέσιμο)" + "Χρώμα Κάθετης Μπάρας Σχολίου 1" + "Εφαρμόστηκε σε: Χρώμα Κάθετης Μπάρας Σχολίου (Επίπεδο 1)" + "Χρώμα Κάθετης Μπάρας Σχολίου 2" + "Εφαρμόστηκε σε: Χρώμα Κάθετης Μπάρας Σχολίου (Επίπεδο 2)" + "Χρώμα Κάθετης Μπάρας Σχολίου 3" + "Εφαρμόστηκε σε: Χρώμα Κάθετης Μπάρας Σχολίου (Επίπεδο 3)" + "Χρώμα Κάθετης Μπάρας Σχολίου 4" + "Εφαρμόστηκε σε: Χρώμα Κάθετης Μπάρας Σχολίου (Επίπεδο 4)" + "Χρώμα Κάθετης Μπάρας Σχολίου 5" + "Εφαρμόστηκε σε: Χρώμα Κάθετης Μπάρας Σχολίου (Επίπεδο 5)" + "Χρώμα Κάθετης Μπάρας Σχολίου 6" + "Εφαρμόστηκε σε: Χρώμα Κάθετης Μπάρας Σχολίου (Επίπεδο 6)" + "Χρώμα Κάθετης Μπάρας Σχολίου 7" + "Εφαρμόστηκε σε: Χρώμα Κάθετης Μπάρας Σχολίου (Επίπεδο 7)" + "Χρώμα Μπάρας Πλοήγησης" + "Εφαρμόστηκε σε: Μπάρα Πλοήγησης" + "Χρώμα Εικονιδίου Σκοτεινής Μπάρας Κατάστασης" + "Χρώμα Εικονιδίου Σκοτεινής Μπάρας Πλοήγησης" + "Αλλαγή Χρώματος Εικονιδίου Μπάρας Κατάστασης μετά την Σύμπτυξη της Γραμμής Εργαλείων στη Καθηλωτική Διεπαφή" + "Διαθέσιμο μόνο για Android 8.0 και πάνω." + "Διαθέσιμο μόνο για Android 6.0 και πάνω." + "Προκαθορισμένα Θέματα" + "Τα Θέματά σας" + "Ποιο είναι το όνομα του θέματος;" + "Όνομα Θέματος" + "Indigo" + "Indigo Σκοτεινό" + "Indigo Amoled" + "Λευκό" + "Λευκό Σκοτεινό" + "Λευκό Amoled" + "Κόκκινο" + "Κόκκινο Σκοτεινό" + "Κόκκινο Amoled" + "Δράκουλας" + "Χαλαρό Παστέλ" + "Φτιάξτε ένα Φωτεινό Θέμα +Βασισμένο στο Θέμα Indigo" + "Φτιάξτε ένα Σκοτεινό Θέμα +Βασισμένο στο Θέμα Indigo Dark" + "Φτιάξτε ένα Θέμα Amoled +Βασισμένο στο Θέμα Indigo Amoled" + "Αν θέλετε να φτιάξετε ένα θέμα βασισμένο σε ένα άλλο θέμα, κάντε κλικ στο κουμπί \"+\" σε ένα θέμα." + "Επεξεργασία Ονόματος Θέματος" + "Επεξεργασία Θέματος" + "Διαγραφή Θέματος" + "Θέλετε σίγουρα να διαγράψετε %1$s;" + "Κοινοποίηση Θέματος" + "Αλλαγή Ονόματος" + "Αντιγράφηκε! Κάντε επικόλληση και μοιραστείτε το με άλλα άτομα." + "Αδυναμία αντιγραφής διαμόρφωσης θέματος " + "Αδυναμία εύρεσης θέματος" + "Εισαγωγή Θέματος" + "Αδυναμία εύρεσης δεδομένων στο πρόχειρο" + "Εισαγωγή Θέματος επιτυχώς" + "Η Δημιουργία Θέματος Απέτυχε" + "Βρέθηκε Διπλότυπο Θέμα" + "Ένα θέμα στη βάση δεδομένων λέγεται επίσης %1$s. Θέλετε να αλλάξετε το όνομα του εισαγόμενου θέματος;" + "Μετονομασία" + "Παράκαμψη" + "Επιλογέας Χρώματος" + "Μη έγκυρ Χρώμα" + "Διαγραφή όλων των subreddits επιτυχώς" + "Διαγραφή όλων των χρηστών επιτυχώς" + "Διαγραφή όλων των τύπων ταξινόμησης επιτυχώς" + "Διαγραφή όλων των διατάξεων ανάρτησης με επιτυχία" + "Διαγραφή όλων των θεμάτων επιτυχώς" + "Διαγραφή όλων των θέσεων σκρολ στην αρχική σελίδα με επιτυχία" + "Έγινε επαναφορά ρυθμίσεων επιτυχώς" + "u/Hostilenemy" + "r/Infinity_For_Reddit" + "Κυρίως Κείμενο" + "Δευτερεύον Κείμενο" + "Αυτό είναι μια ανάρτηση" + "Αυτό το αστείο με τη βαρύτητα έχει παλιωσει, αλλά ακόμα πέφτω κάτω απ' τα γέλια." + "ΑΝΆΡΤΗΣΗ" + "Σήμανση" + "4 Βραβεία" + "Επισήμανση Συντάκτη" + "Πήρα στη κοπέλα μου μια κάρτα «Γίνε καλύτερα». +Δεν είναι άρρωστη ή κάτι, αλλά σίγουρα θα μπορούσε να γίνει καλύτερα." + "Επεξεργασία Multireddit" + "Διαγραφή Multireddit" + "%1$,d Βραβεία" + "1 Βραβείο" + "Αναφορά" + "Αναφέρεται" + "Αναφέρθηκε" + "Η αναφορά απέτυχε" + "Δεν έχετε επιλέξει λόγο" + "Είναι Ανεπιθύμητο" + "Περιέχει πρόβλημα Πνευματικών Δικαιωμάτων" + "Περιέχει Παιδική Πορνογραφία" + "Περιέχει Υβριστικό Περιεχόμενο" + "Αρχική" + "Δημοφιλή" + "Ειδοποιήσεις" + "Μηνύματα" + "Μήνυμα" + "Η ανάκτηση του βίντεο Gfycat απέτυχε" + "Η ανάκτηση του βίντεο Redgifs απέτυχε" + "Ανάκτηση πληροφοριών βίντεο. Παρακαλώ περιμένετε." + "Αδυναμία φόρτωσης εικόνων" + "Γίνεται Λήψη Κομματιού Βίντεο" + "Γίνεται Λήψη Κομματιού Ήχου" + "Πολύπλεξη Βίντεο και Ήχου" + "Αποθηκεύεται το βίντεο" + "Έγινε λήψη" + "Η λήψη απέτυχε: δεν είναι δυνατή η πρόσβαση στη διεύθυνση προσωρινής μνήμης" + "Η λήψη απέτυχε: δεν είναι δυνατή η λήψη βίντεο" + "Η λήψη απέτυχε: δεν είναι δυνατή η αποθήκευση βίντεο στη διεύθυνση προσωρινής μνήμης" + "Η λήψη απέτυχε: δεν είναι δυνατή η αποθήκευση ήχου στη διεύθυνση προσωρινής μνήμης" + "Η λήψη απέτυχε: δεν είναι δυνατή η πολύπλεξη βίντεο και ήχου" + "Η λήψη απέτυχε: δεν είναι δυνατή η αποθήκευση βίντεο στη δημόσια διεύθυνση" + "Η Ταπετσαρία ορίστηκε" + "Αδυναμία ρύθμισης ταπετσαρίας" + "Ρύθμιση στην Αρχική Οθόνη" + "Ρύθμιση στην Οθόνη Κλειδώματος" + "Ρύθμιση και στα δύο" + "Προεπιλογή" + "Προσπάθεια φόρτωσης βίντεο στο Redgifs" + "%1$s βθμ" + "Αν έχετε ενεργή την ταυτοποίηση 2 παραγόντων, παρακαλώ πληκτρολογήστε τον κωδικό με τον παρακάτω τρόπο: <κωδικός>:<2FA κωδικός>. +Παράδειγμα: οκωδικοςσας:123456" + "Αναδημοσίευση" + "Δώστε Βραβείο" + "Αναδημοσίευση" + "Επιλογή Σήμανση Χρήστη" + "Δώσε Βραβείο" + "Αναρτήσεις" + "Μόνο για Συνδεδεμένο Χρήστη" + "Ο Αριθμός Στηλών Στη Ροή Αναρτήσεων" + "Πορτραίτο" + "Οριζόντιος" + "NSFW & Spoiler" + "Διαγραφή Όλων Των Απαρχαιωμένων Ρυθμίσεων" + "Επανεκκινήστε την εφαρμογή για να δείτε τις αλλαγές" + "Αριθμός Καρτελών" + "Εμφάνιση Ονομάτων Καρτελών" + "Περισσότερες Καρτέλες" + "Η ενεργοποίηση των παρακάτω ρυθμίσεων ίσως προκαλεί ανεπιθύμητη συμπεριφορά: +Οι καρτέλες μπορεί να χάσουν όλο το περιεχόμενό τους μόλις γίνει εναλλαγή σε άλλα. Είναι το ίδιο με την ανανέωση της σελίδας." + "Εμφάνιση Αγαπημένων Εγγεγραμμένων Subreddits" + "Εμφάνιση Subreddits που έχετε Εγγραφεί" + "Τοποθεσία Λήψης" + "Τοποθεσία Λήψης Εικόνας" + "Τοποθεσία Λήψης Gif" + "Τοποθεσία Λήψης Βίντεο" + "Διαφορετικός Φάκελος για κάθε Subreddit" + "Ενέργεια Συρσίματος" + "Απενεργοποίηση Συρσίματος Μεταξύ Καρτελών" + "Ενεργοποίηση Ενέργειας Συρσίματος" + "Όριο" + "Τραβήξτε για Ανάρτηση" + "Ασφάλεια" + "Παρατεταμένο Άγγιγμα για Απόκρυψη Γραμμής Εργαλείων" + "Απόκρυψη Γραμμής Εργαλείων από Προεπιλογή" + "Παραμετροποίηση Κάτω Μπάρας Πλοήγησης" + "Κεντρική Σελίδα" + "Άλλες Σελίδες" + "Καταμέτρηση Επιλογής" + "Επιλογή 1" + "Επιλογή 2" + "Επιλογή 3" + "Επιλογή 4" + "Αιωρούμενο Κουμπί Ενέργειας" + "Λειτουργία Εξοικονόμησης Δεδομένων" + "Σε λειτουργία εξοικονόμησης δεδομένων: +Οι προεπισκοπήσεις εικόνες θα είναι σε χαμηλότερη ανάλυση. +Τα βίντεο στο Reddit θα είναι σε χαμηλότερη ανάλυση. +Η αυτόματη αναπαραγωγή βίντεο είναι ανενεργή." + "Μετάφραση" + "Μεταφράστε την εφαρμογή στο POEditor. Ευχαριστώ όλους τους συνεισφέροντες" + "Εθνικές Σημαίες" + "Εικονίδιο έγινε από τον Freepik από www.flaticon.com" + "Η αντιγραφή απέτυχε" + "Διαγραφή όλων των απαρχαιωμένων ρυθμίσεων με επιτυχία" + "Έγινε λήψη" + "Η λήψη απέτυχε: δεν είναι δυνατή η πρόσβαση της διεύθυνσης προορισμού" + "Η λήψη απέτυχε" + "Η λήψη απέτυχε: δεν είναι δυνατή η αποθήκευση του αρχείου στη διεύθυνση προορισμού" + "Η σήμανση χρήστη επιλέχθηκε" + "Επιλογή αυτής σήμανσης χρήσης;" + "Επιλογή Μεγέθους Κεφαλίδας" + "Μεγάλο" + "Μικρό" + "Εισαγωγή Συνδέσμου" + "Κείμενο" + "Σύνδεσμος" + "Τμήμα Ξεκλειδώματος Λογαριασμού" + "Ξεκλείδωμα" + "Υποβολή Ανάρτησης" + "Ανανέωση" + "Αλλαγή τύπου ταξινόμησης" + "Αλλαγή Διάταξης Ανάρτησης" + "Να δωθεί Βραβείο;" + "Ανώνυμος" + "Κωδικός: %1$d/ +Μήνυμα: %2$s" + "Το βραβείο δόθηκε" + "Απέτυχε" + "Προειδοποίηση" + "Πρόκειται για ένα NSFW subreddit." + "Αυτός ο χρήστης έχει περιεχόμενο NSFW" + "Απόρριψη" + "Αποχώρηση" + "Πηγαίνετε στο Subreddit" + "Πηγαίνετε στον Χρήστη" + "Όνομα" + "Τυχαίο" + "Τυχαίο Subreddit" + "Τυχαίο NSFW Subreddit" + "Τυχαία Ανάρτηση" + "Τυχαία NSFW ανάρτηση" + "Προσπαθήστε ξανά αργότερα" + "Γίνεται λήψη" + "r/all και r/popular" + "Λοιπά" + "Σεβασμός του Προτεινόμενου Τύπου Ταξινόμησης Σχολίων του Subreddit" + "Ο τύπος ταξινόμησης των σχολίων δεν θα αποθηκεύεται" + "Απόκρυψη Subreddits" + "Στα r/popular και r/all" + "Εφέ Σύλληψης UFO" + "Επιλογή Ποιότητας Βίντεο" + "Απτική Ανάδραση" + "Απόκρυψη Περιγραφής Subreddit" + "Απενεργοποίηση Προεπισκόπησης Εικόνας στην Λειτουργία Εξοικονόμησης Δεδομένων" + "Σύρετε Αριστερά" + "Σύρετε Δεξιά" + "Δεν εφαρμόζεται σε ροή αναρτήσεων με πάνω από 1 στήλη ή με λεπτομέρειες ανάρτησης." + "Χρώμα Εικονιδίου Ανάρτησης Τύπου Χωρίς-Προεπισκόπηση" + "Εφαρμόστηκε σε: Εικονίδιο που δηλώνει τον τύπο ανάρτησης όταν δεν υπάρχει προεπισκόπηση" + "Χρώμα Παρασκηνίου Τύπου Ανάρτησης Χωρίς Προεπισκόπηση" + "Εφαρμόστηκε σε: Κράτηση Θέσης που δηλώνει τον τύπο ανάρτησης όταν δεν υπάρχει προεπισκόπηση" + "Γλώσσα" + "Παραμετροποίηση Φίλτρου Ανάρτησης" + "Φιλτραρισμένες Αναρτήσεις" + "Φίλτρο Ανάρτησης" + "Χρήστες" + "Επιλέξτε ένα Multireddit" + "Αποθήκευση στη Βάση Δεδομένων" + "Ανάγνωση Όλων των Μηνυμάτων" + "Προσθήκη στο Multireddit" + "Αναζήτηση subreddits" + "Αναζήτηση χρηστών" + "Gif" + "Συλλογή" + "Απενεργοποίηση Καθολικής Διεπαφής" + "Πολιτική Απορρήτου" + "Διαγραφή Όλων των Αναγνωσμένων Αναρτήσεων στη Βάση Δεδομένων" + "Φίλτρο Αναρτήσης" + "Απόκρυψη Προεπισκόπησης μόνο στα Βίντεο και στις Αναρτήσεις Gif" + "Ενεργοποίηση Ιστορικού Αναζήτησης" + "Ιστορικό Αναρτήσεων" + "Επισήμανση Αναρτήσεων ως Αναγνωσμένων" + "Επισήμανση Αναρτήσεων ως Αναγνωσμένων κατά τη Ψήφο" + "Επισήμανση Αναρτήσεων ως Αναγνωσμένων κατά την Κύλιση" + "Αυτόματη Απόκρυψη Αναγνωσμένων Αναρτήσεων" + "Τύπος Ταξινόμησης" + "Αποθήκευση Τύπου Ταξινόμησης" + "Προεπιλεγμένος Τύπος Ταξινόμησης Subreddit" + "Προεπιλεγμένος Χρόνος Ταξινόμησης Subreddit" + "Προεπιλεγμένος Τύπος Ταξινόμησης Χρήστη" + "Προεπιλεγμένος Χρόνος Ταξινόμησης Χρήστη" + "Άνοιγμα Συνδέσμου" + "Επιλέξτε Subreddits και Χρήστες" + "Χρώμα Τίτλου Αναγνωσμένης Ανάρτησης" + "Εφαρμόστηκε σε: Τίτλος Αναγνωσμένης Ανάρτησης" + "Χρώμα Περιεχομένου Αναγνωσμένης Ανάρτησης" + "Εφαρμόστηκε σε: Αναγνωσμένο Περιεχόμενο Ανάρτησης" + "Χρώμα Παρασκηνίου Αναγνωσμένης Ανάρτησης σε Προβολή Κάρτας" + "Εφαρμόστηκε σε: Παρασκήνιο Αναγνωσμένης Ανάρτησης" + "Διαγραφή όλων των αναγνωσμένων αναρτήσεων με επιτυχία" + "Απόκρυψη Αναγνωσμένων Αναρτήσεων" + "Φίλτρο Αναρτήσεων" + "Μόνο NSFW" + "Μόνο Spoiler" + "Τίτλος: εκτός λέξεις-κλειδιά(κλειδι1,κλειδι2)" + "Τίτλος: εκτός regex" + "Εξαίρεση subreddits (πχ. funny, AskReddit)" + "Εξαίρεση χρηστών (πχ. Hostilenemy, random)" + "Εξαίρεση σημάνσεων (πχ. Σήμανση1, Σήμανση2)" + "Συμπερίληψη σημάνσεων (πχ σήμανση1, σήμανση2)" + "Ελάχιστη ψήφος (-1: χωρίς περιορισμούς)" + "Μέγιστοι ψήφοι (-1: χωρίς περιορισμούς)" + "Ελάχιστα σχόλια (-1: χωρίς περιορισμούς)" + "Μέγιστα σχόλια (-1: χωρίς περιορισμούς)" + "Ελάχιστα βραβεία (-1: χωρίς περιορισμούς)" + "Μέγιστα βραβεία (-1: χωρίς περιορισμούς)" + "Όνομα Φίλτρου Ανάρτησης" + "Ποιο είναι το όνομα αυτού του φίλτρου ανάρτησης;" + "%1$s Υπάρχουν Ήδη" + "Παράκαμψη;" + "Εφαρμογή σε" + "Αρχική" + "Subreddit: %1$s" + "Subreddit" + "Χρήστης: %1$s" + "Χρήστης" + "MultiReddit: %1$s" + "MultiReddit" + "Αναζήτηση" + "Subreddit" + "Χρήστης" + "Αφήστε κενό για να γίνει εφαρμογή του φίλτρου ανάρτησης σε όλα τα subreddit/multireddits/χρήστες" + "Το κάνατε πολλές φορές αυτό. Δοκιμάστε ξανά αργότερα. Πρόκειται για όριο συχνότητας του Reddit API." + "Όλα τα μηνύματα αναγνώστηκαν επιτυχώς" + "Αδυναμία ανάγνωσης όλων των μηνυμάτων" + "Το %1$s προστέθηκε στο multireddit %2$s" + "Αδύνατη η προσθήκη του %1$s στο multireddit %2$s" + "Επιλέξτε έναν χρηστη" + "Κάντε κλικ για Εμφάνιση Πολυμέσων στη Διάταξη Συλλογής" + "Απόκρυψη Τύπου Ανάρτησης" + "Απόκρυψη Αριθμού των Βραβείων" + "Απόκρυψη Subreddit και προθέματος Χρήστη" + "Απόκρυψη Αριθμού Ψήφων" + "Απόκρυψη Αριθμού Σχολίων" + "Διάταξη Συλλογής" + "Διάταξη Καρτών 2" + "Υπάρχει πρόβλημα σύνδεσης" + "Θέλετε να δοκιμάσετε κι άλλο τρόπο να συνδεθείτε;" + "Ψήφος" + "Κοινοποίηση Συνδέσμου" + "Αντιγραφή Συνδέσμου" + "Φίλτρο Προσθήκη στην Ανάρτηση" + "Να μην γίνεται θόλωση των εικόνων NSFW στα NSFW Subreddits" + "Εμφάνιση Άβαταρ στα Δεξιά" + "Ρυθμίσεις Αντιγράφων ασφαλείας" + "Ανάκτηση Ρυθμίσεων" + "Εφέ Μου αρέσει" + "Σύρετε Μεταξύ Αναρτήσεων" + "Συρτάρι Πλοήγησης" + "Σύμπτυξη Τμήματος Λογαριασμού" + "Σύμπτυξη Τμήματος Ανάρτησης" + "Σύμπτυξη Τμήματος Προτιμήσεων" + "Σύμπτυξη Τμήματος Αγαπημένων Subreddits" + "Σύμπτυξη Τμήματος Εγγεγραμμένων Subreddits" + "Απόκρυψη Τμήματος Αγαπημένα Subreddits" + "Απόκρυψη Τμήματος Εγγεγραμμένων Subreddits" + "Προεπιλεγμένη Καρτέλα Αποτελεσμάτων Αναζήτησης" + "Προεπιλογή συσκευής" + "Βάσει Εξοικονόμησης Μπαταρίας" + "Χρώμα Εικονιδίου Αναλογίας Θετικών Ψήφων" + "Εφαρμόστηκε σε: Εικονίδιο αναλογίας ψήφων" + "Τρέχων χρήστης" + "Εφαρμόστηκε σε: Τρέχων χρήστης στα σχόλια" + "Εξαίρεση τομέων" + "Ξεκινήστε με το να γίνετε μέλος σε ένα subreddit!" + + + "Οι ρυθμίσεις εξήχθησαν επιτυχώς στη διαδρομή προορισμού." + "Δεν ήταν δυνατή η δημιουργία backup zip στη διεύθυνση προορισμού" + "Δεν ήταν δυνατή η δημιουργία αντιγράφων ασφαλείας κάποιων ρυθμίσεων αλλά άλλες εξήχθησαν επιτυχώς στη διεύθυνση προορισμού" + "Οι ρυθμίσεις επαναφέρθηκαν επιτυχώς. Επανεκκινήστε την εφαρμογή για να δείτε τις αλλαγές." + "Κάποιες ρυθμίσεις μπορεί να μην επαναφέρθηκαν επιτυχώς. Επανεκκινήστε την εφαρμογή για να δείτε τις αλλαγές." + "Δεν είναι δυνατή η επαναφορά των ρυθμίσεων. Το αρχείο είναι μάλλον κατεστραμμένο." + "Δεν είναι δυνατή η προσπέλαση του αρχείου" + "Αν ψάχνετε ένα σημάδι για να μην αυτοκτονήσετε, ορίστε.\u2764" + "Να μην εμφανιστεί ξανά" + "Συνέχεια" + "Αδυναμία ανάκτησης βίντεο v.redd.it: Αδυναμία εύρεσης ανάρτησης" + "Αδυναμία ανάκτησης βίντεο v.redd.it: Αδυναμία εύρεσης ανάρτησης" + "Αδυναμία ανάκτησης βίντεο v.redd.it: Αδυναμία εύρεσης αναγνωριστικού ανάρτησης" + "Πάντα ενεργό" + "Μόνο σε WiFi" + "Ποτέ" + "Κανονικό" + "Πολύ Μεγάλο" + "Υπερβολικά Μεγάλο" + "Προεπιλογή" + "Κλειστό" + "Μόνο σε Δεδομένα Κιν. Τηλεφωνίας" + "Θετική Ψήφος" + "Αρνητική ψήφος" + "Επιλογή" + "Εξαίρεση αυτού του subreddit" + "Εξαίρεση αυτού του χρήστη" + "Εξαίρεση αυτής της σήμανσης" + "Συμπερίληψη αυτής της σήμανσης" + "Εξαίρεση αυτού του τομέα" + "Πρόταση Τίτλου" + "Αποτυχία πρότασης τίτλου" + "Διαγραφή Logs" + "Εισερχόμενα (%1$,d)" + "Συνεχίστε το νημα" + "Σύρετε Κάθετα για να Επιστρέψετε από μια Εικόνα ή gif" + "Απόκρυψη Σήμανσης Ανάρτησης" + "Αναφορές Σφαλμάτων" + "Επικίνδυνο" + "Απενεργοποίηση NSFW για πάντα" + "Εμφάνιση Μόνο Μιας Ένδειξης Επιπέδου Σχολίου" + "Αποθήκευση" + "Μη Αποθήκευση" + "Αντιγραφή Μονοπατιού Multireddit" + "Αδυναμία αντιγραφής μονοπατιού multireddit" + "Οι αναφορές σφαλμάτων έχουν διαγραφεί" + "Μόλις ενεργοποιηθεί, τα NSFW θα απενεργοποιηθούν μόνιμα, ανεξάρτητα από το αν η ρύθμιση NSFW είναι ενεργή ή όχι. Η επιλογή είναι μη αναστρέψιμη και ο μόνος τρόπος για να τα ενεργοποιήσετε ξανά είναι η εκκαθάριση δεδομένων της εφαρμογής. + +Θέλετε σίγουρα να το ενεργοποιήσετε;" + "Απάντηση" + "Ανάρτηση Εικόνας" + "Σε τάση" + "Κοινοποίηση Συνδέσμου Ανάρτησης" + "Σε τάση" + "Λήψη μόνο ειδοποιήσεων απαντήσεων σε αναρτήσεις" + "Γκαλερί" + "Συλλογή Αναρτάται" + "Reddit" + "Προεπιλεγμένη Διάταξη Συνδέσμου Ανάρτησης" + "Material You" + "Σιγουρευτείτε ότι δεν έχετε θέματα με όνομα +\"Material You\", +\"Material You Dark\" ή +\"Material You Amoled\". +Ειδάλλως, μετονομάστε πριν την ενεργοποίηση του Material You." + "Ενεργοποίηση Material You" + "Κάντε το Infinty πιο προσωπικό βάσει της Ταπετσαρίας Σας" + "Εφαρμογή Material You" + "Σε περίπτωση που το Infinity δεν άλλαξε το θέμα" + "Εμφάνιση Αγαπημένων Multireddits" + "Εμφάνιση Multireddits" + "Σύμπτυξη Τμήματος Reddit" + "Αυτόματη εναλλαγή σε οριζόντιο προσανατολισμό στον Αναπαραγωγέα Βίντεο" + "Να θυμάσαι την Επιλογή Σίγασης στη Ροή Αναρτήσεων" + "Αυτόματο" + "Ανεβασμένες Εικόνες" + "Επιλέξτε μια Εικόνα" + "Καταγραφή" + "Μεταμόρφωση" + "Μεταμόρφωση εικόνας με επιτυχία. Κάντε κλικ στο κουμπί εικόνας ξανά για να δείτε τις ανεβασμένες εικόνες." + "Αδυναμία απόκτησης bitmap της εικόνας" + "Αδυναμία μεταμόρφωσης της εικόνας" + "Αναζήτηση Σχολίων" + "Μια εικόνα μεταμορφώνεται ακόμα. Παρακαλώ περιμένετε." + "Η ανάκτηση αναζητήσεων σε τάση απέτυχε. +Αγγίξτε για επανάληψη." + "Η γέννηση αναζητήσεων σε τάση απέτυχε. +Αγγίξτε για επανάληψη." + "Δε βρέθηκαν αναζητήσεις σε τάση. +Αγγίξτε για επανάληψη." + "Βίκι" + "Πληροφορίες Ανάρτησης" + "Διαχωρισμός Αναρτήσεων Και Σχολίων σε Οριζόντιο Προσανατολισμό" + "Διαχωρισμός Αναρτήσεων Και Σχολίων σε Κάθετο Προσανατολισμό" + "Η αυτόματη αναπαραγωγή βίντεο θα είναι ανενεργή στη σελίδα λεπτομερειών της ανάρτησης" + "Χρήση Κάτω Γραμμής Εργαλείων στον Προβολέα Πολυμέσων" + "Ασφαλής Λειτουργία" + "Στιγμιότυπο και καταγραφή οθόνης δεν επιτρέπονται. Δεν γίνεται προεπισκόπηση στην οθόνη πρόσφατων εφαρμογών." + "Απόρριψη" + "Αδυναμία φόρτωσης wiki" + "Αυτό το subreddit δεν έχει σελίδα wiki" + "Εφαρμόζεται το Material You" + "Πήγαινε στο Wiki" + "Ταχύτητα Αναπαραγωγής" + "Σχετικά" + "Διαχειριστής Συνδέσμου" + "Ενέργεια Κουμπιού Πίσω Κυρίας Σελίδας" + "Άνοιγμα Συρταριού Πλοήγησης" + "Πορτραίτο (Ξεδιπλωμένο)" + "Οριζόντιος (Ξεδιπλωμένο)" + "Βίντεο σε Βρόχο" + "Επανεκκινήστε την εφαρμογή για εφαρμογή ρυθμίσεων αυτόματης αναπαραγωγής βίντεο" + "Εφέ Οθόνης Κλειδώματος" + "Κλείδωμα Εφαρμογής" + "Απαίτηση ταυτοποίησης πριν τη χρήση της εφαρμογής" + "Χρονικό Όριο Κλειδώματος Εφαρμογής" + "Ενεργοποίηση υποστήριξης αναδιπλούμενης συσκευής" + "Προεπιλεγμένη Ταχύτητα Αναπαραγωγής" + "Εξωτερική Εφαρμογή" + "Προσαρμοσμένη Καρτέλα" + "Εσωτερικός Περιηγητής" + "Απαρχαιωμένο UI χειριστηρίου Βίντεο" + "Τσιμπήστε για Ζουμ Βίντεο" + "Πειραματική λειτουργία" + "Χρώμα Εικονιδίου Ένδειξης Πολυμέσων" + "Εφαρμόστηκε σε: Εικονίδιο Βίντεο ή εικόνας στην προεπισκόπηση ανάρτησης" + "Χρώμα Παρασκηνίου Ένδειξης Πολυμέσων" + "Εφαρμόστηκε σε: Παρασκήνιο εικονιδίου βίντεο ή συλλογής στην προεπισκόπηση ανάρτησης" + "Άλμα προς τα Πάνω" + "Τίτλος: περιέχει λέξεις κλειδιά (κλειδι1,κλειδι2)" + "Τίτλος: περιέχει regex" + "Συμπερίληψη τομέων" + "Αυτό το multireddit δεν έχει subreddit!" + "Αδυναμία ανάκτησης βίντεο v.redd.it: Αδυναμία εύρεσης συνδέσμου βίντεο" + "Συμπερίληψη αυτού του τομεα" + "Μισό λεπτό!!!" + "Αμέσως" + "1 λεπτό" + "2 λεπτά" + "5 λεπτά" + "10 λεπτά" + "15 λεπτά" + "20 λεπτά" + "30 λεπτά" + "1 ώρα" + "2 ώρες" + "3 ώρες" + "4 ώρες" + "5 ώρες" + "6 ώρες" + "12 ώρες" + "24 ώρες" + "Επεξεργασία Προφίλ" + "Επικοινωνία με Συντονιστές" + "Αποθήκευση NSFW Πολυμέσων σε Άλλη Τοποθεσία" + "Τοποθεσία Λήψης NSFW" + "Η ανάκτηση του βίντεο Gfycat απέτυχε" + + + "Υποβολή Αλλαγής Άβαταρ" + "Υποβολή Αλλαγής Μπάνερ" + "Υποβολή Αποθήκευσης Προφίλ" + + + "Επεξεργασία Προφίλ" + "Αφαίρεση Άβαταρ" + "Αφαίρεση Μπάνερ" + "Όνομα Εμφάνισης" + "Εμφάνιση στη σελίδα προφίλ σας" + "Αυτό θα φαίνεται προβάλλεται στα άτομα που βλέπουν τη σελίδα του προφίλ σας και δεν αλλάζει το όνομα χρήστη σας." + "Σχετικά με σένα" + "Μια περιγραφή για σένα" + "Το άβαταρ αφαιρέθηκε επιτυχώς" + "Αποτυχία αφαίρεσης άβαταρ %s" + "Το άβαταρ αφαιρέθηκε επιτυχώς" + "Αποτυχία αφαίρεσης μπάνερ %s" + "Το άβαταρ άλλαξε επιτυχώς" + "Αποτυχία αλλαγής άβαταρ %s" + "Το μπάνερ άλλαξε επιτυχώς" + "Αποτυχία αλλαγής banner %s" + "Το προφίλ αποθηκεύτηκε επιτυχώς" + "Αποτυχία αποθήκευσης προφίλ %s" + "Ανάρτηση Δημοσκόπησης" + "Άνοιγμα σε περιηγητή" + "Διάρκεια Δημοσκόπησης: %1$d μέρες" + "Μια καλή δημοσκόπηση χρειάζεται τουλάχιστον 2 επιλογές!" + "Δημοσκόπηση" + "Δεν υπάρχει εφαρμογή που μπορεί να χειριστεί την ενέργεια άνοιγμα σε εξωτερική εφαρμογή" + "Απαίτηση Αυθεντικοποίησης για Εμφάνιση Λογαριασμών" + "Προσαρμοσμένη Γραμματοσειρά" + "Προσαρμοσμένη Γραμματοσειρά Τίτλων" + "Προσαρμοσμένη Γραμματοσειρά Περιεχομένου" + "Σταθερό Ύψος στην Κάρτα" + "Απόκρυψη Περιεχομένου Κειμένου Ανάρτησης" + "Απόκρυψη Βραβείων Σχολίου" + "Εμφάνιση Λιγότερων Επιλογών Γραμμής Εργαλείων Ξεκινώντας από" + Επίπεδο %1$d + "Εμφάνιση Άβαταρ Συντάκτη" + "Συμφωνητικό Χρήσης Reddit" + "Εμφάνιση Αριθμού Θυγατρικών Σχολίων Πάντα" + "Απόκρυψη Αναλογίας Ψήφων" + "Επικίνδυνο" + "Αυξήστε την τιμή για εμφάνιση προεπισκοπήσεων σε μεγαλύτερη ανάλυση αλλά, η εφαρμογή μπορεί να τερματιστεί απροσδόκητα." + "Μέγιστη Ανάλυση Προεπισκόπησης Ροής Αναρτήσεων (Πλάτος*Ύψος)" + "Προεπιλεγμένη Ανάλυση Βίντεο Reddit" + "Επιλέξτε αρχείο γραμματοσειρές ttf" + "Αδυναμία απόκτησης της γραμματοσειράς σας" + "Αδυναμία φόρτωσης προσαρμοσμένης γραμματοσειράς" + "Αδυναμία αντιγραφής της γραμματοσειράς σας" + "Περιγραφή (έως 180 χαρακτήρες)" + "Url" + "Συμφωνητικό Χρήστη" + "Πρέπει να συμφωνήσετε με το Συμφωνητικό Χρήστη (%1$s) και την Πολιτική Απορρήτου του Infinity για το Reddit (%2$s) πριν συνδεθείτε." + "Συμφωνώ" + "Δεν Συμφωνώ" + "Επιλογή 1 (Απαιτείται)" + "Επιλογή 2 (Απαιτείται)" + "Επιλογή 3" + "Επιλογή 4" + "Επιλογή 5" + "Επιλογή 6" + "Μη έγκυρος αριθμός" + "Κάρμα Αναρτήσεων:" + "Κάρμα Σχολίων:" + "Κάρμα Βραβευτή:" + "Κάρμα Βραβευμένου:" + "Ιστορικό" + "Ιστορικό" + "Ευκολότερο στη θέαση στην Πλήρη Οθόνη" + "Εκκαθάριση Σήμανσης" + "Η σήμανση χρήστη καθάρισε" + "Πολύ Μικρό" + "Χειρισμός συνδέσμου" + "Μη έγκυρος σύνδεσμος" + "Τα πολυμέσα περιλαμβάνουν κομμάτια βίντεο, αλλά κανένα δεν είναι δυνατόν να αναπαραχθεί σ'αυτή τη συσκευή" + "Τα πολυμέσα περιλαμβάνουν κομμάτια ήχου, αλλά κανένα δεν είναι δυνατόν να αναπαραχθεί σ'αυτή τη συσκευή" + "Αύξηση Έντασης" + "Χωρίς Ένταση" + "Αποκλεισμός Χρήστη" + "Δημιουργία GitHub Issue" + "Περισσότερες επιλογές" + "Ο κωδικός αρχείου αντιγράφου ασφαλείας είναι \"123321\"." + "Απόκρυψη Κάρμα Λογαριασμού" + "Απόκρυψη FAB στην ροή Αναρτήσεων" + "Τύπος Διαχωριστή Σχολίων" + "Αποκλεισμός Χρήστη" + "Αποκλείστηκε" + "Αποτυχία αποκλεισμού χρήστη" + "Μη έγκυρο μοτίβο regex" + "Αποτυχία φόρτωσης περισσότερων αναρτήσεων. +Αγγίξτε για επανάληψη." + "Όχι άλλες αναρτήσεις" + "%1$d/%2$d" + "Δεν χορηγήθηκε άδεια για ειδοποιήσεις" + "Ρυθμίσεις" + "Συνδρομή" + "Επεξεργάστηκε" + "Επεξεργάστηκε στις %s" + "Καλώς ήρθατε στο Infinity για το Reddit, η πύλη σας για μια νέα διάσταση περιήγησης στο Reddit!" + + + "Πριν μπείτε στον κόσμο των αμέτρητων πιθανοτήτων που προσφέρει η εφαρμογή, θέλω να είμαι ξεκάθαρος για μια σημαντική ααλλαγή που έχω ενσωματώσει για σιγουρευτώ ότι θα έχετε την καλύτερη δυνατή υπηρεσία. + +Από 'δώ και πέρα, θα χρειάζεστε μηνιαία συνδρομή για τη χρήση του Reddit API εντός του Infinity για το Reddit και αυτό επειδή το Reddit άρχισε να χρεώνει τη πρόσβαση του API από τις 1 Ιουλίου 2023." + "Μηνιαία" + "Ετήσια" + "Εβδομαδιαία" + "Η υπηρεσία χρέωσης δεν υποστηρίζεται στη συσκευή" + "Ο δημιουργός έκανε κάποια λάθη. Δεν είναι δικό σας λάθος." + "Μοιραίο σφάλμα κατά την ενέργεια API." + "Η αιτούμενη δυνατότητα δεν υποστηρίζεται από το Play Store στην τρέχουσα συσκευή." + "Η αγορά απέτυχε επειδή το αντικείμενο έχει ήδη αγοραστεί." + "Το αιτούμενο προϊόν δεν είναι διαθέσιμο για αγορά." + "Προέκυψε σφάλμα δικτύου κατά την διαδικασία." + "Η εφαρμογή δεν είναι συνδεδεμένη στην υπηρεσία Play Store μέσω της Βιβλιοθήκης Google Play Billing." + "Η υπηρεσία δεν είναι διάθεση για την ώρα." + "Η συναλλαγή ακυρώθηκε από τον χρήστη" + "Χάλκινο" + "Ασημένιο" + "Χρυσό - Τέλεια Επιλογή!" + "Πλατινένιο" + "Διαμάντι" + "Άπειρο" + "Δεν είναι δυνατή η αναγνώριση χρέωσης" + "Αποτυχία σύνδεσης στο σύστημα χρέωσης" + "Σύνδεση στο σύστημα χρέωσης. Παρακαλώ περιμένετε." + "Ευχαριστούμε για τη συνδρομή σας" + "Φόρτωση επιλογών συνδρομής" + "Αναγνώριση της συνδρομής σας. Παρακαλώ περιμένετε." + "Ουψ, υπήρξε ένα σφάλμα κατά την αναγνώριση της αγοράς σας. Αν το πρόβλημα παραμένει για 3 μέρες, θα λάβετε αυτόματα επιστροφή χρημάτων. +Μην ανησυχείτε, μπορείτε και πάλι να απολαμβάνετε το Infinity για το Reddit. " + "Συνέχεια στην εφαρμογή" + "Πληρώσατε ήδη για τη συνδρομή;" + "Επαναφορά αγοράς συνδρομής" + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml new file mode 100644 index 00000000..6be51231 --- /dev/null +++ b/app/src/main/res/values-ko/strings.xml @@ -0,0 +1,520 @@ + + + "로그인" + "댓글 전송" + "답장" + "텍스트 글" + "서브레딧 선택" + "링크 글" + "사진 글" + "둥영상 글" + "규칙" + "서브레딧" + "글 편집" + "댓글 편집" + "받은편지함" + "설정" + "저장함" + "멀티레딧 생성" + "서브레딧 선택" + "커스텀 테마" + "테마 편집하기" + "테마 만들기" + "테마 미리보기" + "멀티레딧 편집" + "선택된 서브레딧" + "신고" + + + "사진 %1$d/%2$d" + + + "둥영상 %1$d/%2$d" + "개인 메시지 보내기" + + + "사진 %1$d/%2$d" + + + "Gif %1$d/%2$d" + + + "둥영상 %1$d/%2$d" + "네비게이션 드로어 열기" + "네비게이션 드로어 닫기" + "다운로드" + "새로 고침" + "댓글 추가" + "글 저장" + "글 원본 보기" + "검색" + "게으른 모드 시작" + "게으른 모드 중지" + "전송" + "정렬" + "글 숨기기" + "글 숨기기 해제" + "글 편집" + "글 삭제" + "NSFW 표기" + "NSFW 표기 해제" + "스포일러 표기" + "스포일러 표기 해제" + "플레어 편집" + "글 레이아웃 변경" + "저장" + "멀티레딧 편집" + "멀티레딧 삭제" + "공유" + "미리 보기" + "신고" + "삭제된 항목 보기" + "배경화면으로 설정" + "개인 메시지 보내기" + "JSON 답변을 파싱하는데 오류가 발생했습니다" + "토큰을 가져오는데 실패했습니다" + "문제가 생겼습니다. 나중에 다시 시도하세요." + "접근 금지됨" + "사용자 정보를 파싱하는데 오류가 발생했습니다" + "시스템의 웹뷰를 여는데 오류가 발생했습니다" + "사진을 로드하는데 오류가 발생했습니다. 재시도하려면 탭하세요." + "글들을 불러오는데 오류가 발생했습니다. +재시도하려면 탭하세요." + "글들을 불러오는데 오류가 발생했습니다." + "이 글을 로드하는데 오류가 발생했습니다. +재시도하려면 탭하세요." + "서브레딧을 검색하는데 오류가 발생했습니다. +재시도하려면 탭하세요." + "사용자를 검색하는데 오류가 발생했습니다. +재시도하려면 탭하세요." + "글들을 찾지 못함" + "댓글들을 찾지 못함" + "서브레딧들을 찾지 못함" + "사용자들을 찾지 못함" + "멀티레딧들을 찾지 못함" + "이 파일을 저장할 저장소 권한이 없음" + "댓글들을 불러오는데 오류가 발생했습니다. +재시도하려면 탭하세요." + "재시도" + "댓글들" + "댓글이 아직 없습니다. 댓글을 쓸까요?" + "투표 실패" + "글을 새로 고침하는데 오류가 발생했습니다" + "메시지들을 로드하는데 오류가 발생했습니다. +재시도하려면 탭하세요." + "비어 있음" + "NSFW" + + + "카르마: %1$d" + + + "카르마: +%1$d (%2$d + %3$d)" + "케이크날: +%1$s" + "가입:" + "프로필" + "구독" + "멀티레딧" + "받은편지함" + "+1 투표함" + "-1 투표함" + "숨김" + "저장됨" + "선물 단 글" + "설정" + + + "구독자 수: %1$d" + + + "온라인: %1$d" + "서브레딧 정보 불러올 수 없음" + "사용자 정보 불러올 수 없음" + "사이드바 불러올 수 없음" + "멀티레딧 불러올 수 없음" + "구독하기" + "구독 해제하기" + "구독됨" + "구독 실패" + "구독 해제됨" + "구독 해제 실패" + "팔로우" + "언팔로우" + "팔로우됨" + "팔로우 실패" + "언팔로우됨" + "언팔로우 실패" + "서브레딧 배너 사진" + "인피니티" + "아무거나 검색" + "글 없음" + "게으른 모드는 %1$.1fs 이후 시작됩니다" + "게으른 모드 중지됨" + "흥미로운 생각들 여기에 적기" + "흥미로운 생각이 무엇인가요?" + "전송 중" + "댓글 전송됨" + "이 댓글을 전송할 수 없습니다" + "사용자" + "제목 (최대 100자)" + "메시지" + "이 메시지에 답변할 수 없습니다" + "이 메시지를 불러오는데 오류가 발생했습니다" + "누구에게 이 메시지를 전송할까요?" + "메시지는 제목을 필요로 합니다" + "메시지는 내용을 필요로 합니다" + "전송 중" + "메시지 전송됨" + "이 메시지를 전송할 수 없습니다" + "서브레딧을 먼저 선택하세요" + + + "글은 좋은 제목이 필요합니다" + "링크가 어디 있죠?" + "사진을 먼저 선택하세요" + "글 게시 중" + "게시에 실패했습니다" + "사진 처리에 오류가 발생했습니다" + "둥영상 처리에 오류가 발생했습니다" + "다운로드가 시작되었습니다. 알림창에서 진행 상태를 확인하세요." + "댓글들 더 불러오기" + "불러오기에 실패했습니다. 재시도하려면 탭하세요." + "로딩 중" + "제목" + "내용" + "서브레딧을 선택하세요" + "규칙" + "URL" + "서브레딧들" + "사용자들" + "멀티레딧들" + "텍스트" + "링크" + "사진" + "둥영상" + "사진을 선택하기" + "다시 선택" + "사진을 불러오는데 오류가 발생했습니다" + "둥영상을 불러오는데 오류가 발생했습니다" + "사용 가능한 카메라 어플이 없습니다" + "임시 파일을 생성하는데 오류가 발생했습니다" + "둥영상을 처리중입니다. 잠시만 기다려주세요." + "사진을 처리중입니다. 잠시만 기다려주세요." + "Gif를 처리중입니다. 잠시만 기다려주세요." + "플레어" + "스포일러" + "플레어 없음" + "플레어를 로드하는데 오류가 발생했습니다. +재시도하려면 탭하세요." + + + "규칙 없음" + "규칙을 로드하는데 오류가 발생했습니다. +재시도하려면 탭하세요." + "규칙을 로드하는데 오류가 발생했습니다" + "여기에서 검색" + "모든 서브레딧" + "최고" + "인기" + "신규" + "랜덤" + "상승세" + "톱" + "논쟁성" + "관련성" + "댓글들" + "활성" + "확신성" + "예전" + "QA" + "실시간" + "시간" + "일" + "주" + "월" + "년" + "전체" + "공유를 할 수 있는 어플이 없습니다" + "보관된 글. 투표할 수 없습니다." + "보관된 글. 댓글을 달 수 없습니다." + "보관된 글. 답장할 수 없습니다." + "잠긴 글. 댓글을 달 수 없습니다." + "잠긴 글. 답장할 수 없습니다." + "텍스트" + "링크" + "사진" + "비디오" + "GIF" + "갤러리" + "최고" + "검색" + "둥영상 올리는 중" + "사진 올리는 중" + "기다려 주세요" + + + "계정 추가" + "익명" + "로그아웃" + "여기를 눌러 로그인하세요" + "먼저 로그인하세요" + "글 저장됨" + "글을 저장할 수 없습니다" + "글 저장 해제됨" + "글을 저장 해제할 수 없습니다" + "글 숨겨짐" + "글을 숨길 수 없습니다" + "글 숨김 해제됨" + "즐겨찾기 설정 실패" + "즐겨찾기 해제 실패" + "글을 숨김 해제할 수 없습니다" + "이 글 삭제" + "이 댓글 삭제" + "정말로 실행할까요?" + "편집" + "삭제" + "삭제된 댓글 보기" + "삭제된 댓글 가져오는 중" + "삭제된 댓글을 찾을 수 없습니다" + "삭제된 글 가져오는 중" + "삭제된 글을 찾을 수 없습니다" + "취소" + "확인" + "성공적으로 편집" + "성공적으로 삭제" + "삭제 실패" + "성공적으로 NSFW 표기" + "NSFW 표기 실패" + "성공적으로 NSFW 표기 해제" + "NSFW 표기 해제 실패" + "성공적으로 스포일러 표기" + "스포일러 표기 실패" + "성공적으로 스포일러 표기 해제" + "스포일러 표기 해제 실패" + "성공적으로 플레어 변경" + "플레어 변경에 실패했습니다" + "플레어 편집" + "64자 이하로만 허용" + "여기를 눌러 모든 댓글을 확인하세요" + "계정" + "새로운 메시지" + "서브레딧" + "수상" + + + "%1$d 개의 새 메세지" + "계정" + "게시" + "설정" + "계정이 변경되었습니다. 다른 모든 페이지가 제거되었습니다." + "알림" + "알림 활성화" + "알림 확인 주기" + "테마" + "아몰레드 다크" + "인터페이스" + "제스처와 버튼" + "홈에서 스크롤 위치 저장" + "홈에서 새로고침후 새게시글 둘러보기(프론트 페이지, 정렬기준:최고)" + "둥영상" + "둥영상 자동 재생" + "자동 재생된 둥영상 음소거" + "NSFW 둥영상 자동 재생" + "화면에 보이지 않아도 자동재생(초상화)" + "영상이 보일시 자동재생" + "화면에 보이지 않아도 자동재생(렌드스케이프)" + "보일경우 자동재생 비활성화" + "모든 페이지에 적용되지 않음" + "메인 페이지에 커스터마이징 탭" + "하단 내비게이션 활성화" + "게시글과 댓글" + "투표버튼 우측으로 이동" + "볼륨키로 게시글 댓글 이동" + "볼륨 키로 포스트 스크롤하기" + "둥영상 음소거" + "NSFW 둥영상 음소거" + "Gfycat 비디오가 제거되었을 시 자동으로 Redgifs 접근 시도하기" + "영상에서 내비게이션 바 무시" + "나갈 때 확인" + "댓글" + "가장 높은 댓글 우선 표시" + "터치하여 댓글 툴바 표시/숨기기" + "댓글 숨기기" + "댓글 툴바 기본으로 숨김" + "투표수 표시" + "게시글과 댓글 지나간시간 표시" + "시간 형식" + "글" + "기본 글 레이아웃" + "썸네일 좌측으로 표시" + "댓글에서 터치와 길게 누르는걸 변경" + "오른쪽으로 밀어 돌아가기" + "모든 페이지에 적용되지않음" + "내비게이션 바 잠근" + "게으른 모드 간격" + "폰트" + "폰트 미리보기" + "폰트" + "제목" + "콘텐츠" + "NSFW 활성화" + "NSFW 사진 흐리게 하기" + "스포일러 사진 흐리게 하기" + "정보" + "크레딧" + "로켓 아이콘" + "오픈 소스" + "어플을 좋아한다면 깃허브에서 별표하세요" + "구글 플레이에서 리뷰" + "별표 5점을 주신다면 감사하겠습니다" + "이메일" + "docilealligator.app@gmail.com" + "레딧 계정" + "u/Hostilenemy" + "서브레딧" + "r/Infinity_For_Reddit" + "공유" + "버전 %s" + "라이트 테마" + "다크 테마" + "아몰레드 테마" + "테마 관리" + "고급" + "데이터베이스의 모든 서브레딧 삭제" + "데이터베이스의 모든 사용자 삭제" + "모든 설정 초기화" + "공유" + "이메일 클라이언트 찾을 수 없음" + "사용 가능한 어플 없음" + "댓글 저장됨" + "댓글 저장 실패" + "댓글 저장 해제됨" + "댓글 저장 해제 실패" + "모두" + "카드 레이아웃" + "방금" + "1분" + + + "%1$d분" + "1시간" + + + "%1$d시간" + "어제" + + + "%1$d일" + "1달" + + + "%1$d달" + "1년" + + + "%1$d년" + "멀티레딧 데이터를 가져오는데 오류가 발생했습니다" + "멀티레딧 동기화를 할 수 없음" + "글 링크 공유" + "사진 링크 공유" + "Gif 링크 공유" + "둥영상 링크 공유" + "링크 공유" + "글 링크 복사" + "사진 링크 복사" + "Gif 링크 복사" + "둥영상 링크 복사" + "링크 복사" + "복사됨" + "링크를 복사할 수 없습니다" + "복사" + "모두 복사" + "Markdown 복사" + "원본 텍스트 복사" + "모든 Markdown 복사" + "모든 원본 텍스트 복사" + "종료?" + "라이트 테마" + "다크 테마" + "이름 (최대 50자)" + "설명" + "이름이 무엇인가요?" + "이 멀티레딧을 생성할 수 없음" + "이 멀티레딧은 이미 존재합니다" + "이 멀티레딧을 편집할 수 없음" + + + "성공적으로 삭제" + "삭제 실패" + "정말로 삭제할까요?" + "NSFW 활성화" + "NSFW 비활성화" + "이 사진을 저장할 수 없습니다" + "이 gif를 저장할 수 없습니다" + "어플 저장소에 접근할 수 없습니다" + "사진을 저장 중입니다. 잠시만 기다려주세요." + "Gif를 저장 중입니다. 잠시만 기다려주세요." + "이 테마의 이름을 바꾸려면 탭하세요." + "라이트 테마로 설정" + "다크 테마로 설정" + "아몰레드 테마로 설정" + "주 색상" + "적용 대상: 툴바" + "다크 주 색상" + "적용 대상: 상태표시줄" + "악센트 색상" + "적용 대상: 진행표시줄 등" + "라이트 테마 주 색상" + "적용 대상: 플로팅 액션 버튼과 버튼 배경" + "주 글씨 색상" + "적용 대상: 주 글씨" + "보조 글씨 색상" + "적용 대상: 보조 글씨" + "글 제목 색상" + "적용 대상: 글 제목" + "글 내용 색상" + "적용 대상: 글 내용" + "댓글 색상" + "적용 대상: 댓글" + "버튼 글씨 색상" + "적용 대상: 버튼의 글씨" + "칩 글씨 색상" + "적용 대상: 구독 버튼" + "링크 색상" + "적용 대상: URL" + "받은 메시지 글씨 색상" + "적용 대상: 받은 개인 메시지" + "보낸 메시지 글씨 색상" + "적용 대상: 보낸 개인 메시지" + "배경 색상" + "적용 대상: 모든 페이지의 배경과 네비게이션 드로어" + "카드 뷰 배경 색상" + "스포일러 배경 색상" + "스포일러 글씨 색상" + "구독됨" + "적용 대상: 구독 해제 버튼" + "구독 해제됨" + "적용 대상: 구독 버튼" + "NSFW와 스포일러" + "구독한 서브레딧 보기" + "스포일러만" + "위험" + "정보" + "볼륨 올리기" + "볼륨 끄기" + "유저차단" + "깃허브 문제 생성" + "더많은 설정" + "백업 파일 비밀번호는 \"123321\"." + "계정 카르마 숨기기" + "게시글 피드에 FAB 숨기기" + "유저 차단" + "차단됨" + "유저 차단 실패" + "게시글 불러오는데 실패했습니다. 다시 눌러 시도하세요." + "게시글 없음" + "알림 권한이 허용되지 않았습니다" + "설정" + \ No newline at end of file diff --git a/app/src/main/res/values-night-v31/styles.xml b/app/src/main/res/values-night-v31/styles.xml new file mode 100644 index 00000000..15cbc5cf --- /dev/null +++ b/app/src/main/res/values-night-v31/styles.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index ab122c9c..9ad857bd 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -3,7 +3,7 @@ #242424 #121212 #FF1868 - #88000000 + #00000000 #121212 #FFFFFF #242424 diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml new file mode 100644 index 00000000..c79bb571 --- /dev/null +++ b/app/src/main/res/values-ta/strings.xml @@ -0,0 +1,754 @@ + + + "உள்நுழை" + "கருத்தனுப்பு" + "பதிலளி" + "உரை இடுகை" + "துணைரெட்டிடைத் தேர்ந்தெடு" + "இணைப்பு இடுகை" + "பட இடுகை" + "காணொளி இடுகை" + "விதிகள்" + "துணைரெட்டிட்" + "இடுகையைத் திருத்து" + "கருத்தைத் திருத்து" + "உட்பெட்டி" + "அமைவுகள்" + "சேமித்தவை" + "பல்ரெட்டிட்டை உருவாக்கு" + "துனைரெட்டிட்களைத் தேர்ந்தெடு" + "தனிப்பயன் தோற்றங்கள்" + "தோற்றத்தைத் தனிப்பயனாக்கு" + "தோற்றம் உருவாக்கு" + "தோற்றம் முன்னோட்டம்" + "பல்ரெட்டிட்டைத் திருத்து" + "தேர்ந்த துணைரெட்டிட்கள்" + "புகாரளி" + + + "படம் %1$d/%2$d" + + + "காணொளி %1$d/%2$d" + "PM அனுப்பு" + + + "படம் %1$d/%2$d" + + + "காணொளி %1$d/%2$d" + "வழிசெலுத்தல் அலமாரியைத் திற" + "வழிசெலுத்தல் அலமாரியை மூடு" + "பதிவிறக்கு" + "புத்துணர்வூட்டு" + "கருத்தைச் சேர்" + "இடுகையைச் சேமி" + "குறுக்கிடுகையின் பெற்றோரைப் பார்" + "தேடு" + "சோம்பல் பயன்முறையைத் துவக்கு" + "சோம்பல் பயன்முறையை நிறுத்து" + "அனுப்பு" + "வரிசைப்படுத்து" + "இடக்கையை மறை" + "இடுகையைக் காண்பி" + "இடக்கையைத் திருத்து" + "இடுகையை அழி" + "NSFW என குறி" + "NSFW என குறிக்காதே" + "கெடுப்பியென குறி" + "கெடுப்பியென குறிக்காதே" + "இடுகை தளவமைப்பை மாற்று" + "சேமி" + "பல்ரெட்டிட்டைத் திருத்து" + "பல்ரெட்டிட்டை அழி" + "பகிர்" + "முன்னோட்டம்" + "புகாரளி" + "நீக்கியவற்றைப் பார்" + "சுவரொட்டியாக அமை" + "தனித் தகவல் அனுப்பு" + "JSON பதிலைக் கூறாக்கும்போது பிழை ஏற்பட்டது" + "கிள்ளாக்கைப் பெறுவதில் பிழை" + "ஏதோ தவறானது. பின்னர் மீண்டும் முயல்க." + "அணுகல் மறுப்பு" + "பயனர் தகவலைக் கூறாக்கும்போது பிழை ஏற்பட்டது" + "இயங்குதளத்தின் வலைப்பார்வையைத் திறப்பதில் பிழை" + "படத்தை ஏற்றுவதில் பிழை. மறுமுயல தட்டுக." + "இடுகைகளை ஏற்றுவதில் பிழை. +மறுமுயல தட்டுக." + "இடுகைகளை ஏற்றுவதில் பிழை." + "இவ்விடுகையை ஏற்றுவதில் பிழை. +மறுமுயல தட்டுக." + "துணைரெட்டிட்டுகளைத் தேடுவதில் பிழை. +மறுமுயல தட்டுக." + "பயனர்களைத் தேடுவதில் பிழை. +மறுமுயல தட்டுக." + "இடுகைகள் ஏதுமில்லை" + "கருத்துகள் ஏதுமில்லை" + "துணைரெட்டிடுகள் ஏதுமில்லை" + "பயனர்கள் எவருமில்லை" + "பல்ரெட்டிட்டுகள் ஏதுமில்லை" + "இக்கோப்பைச் சேமிக்க சேமிப்பக அனுமதி இல்லை" + "கருத்துகளை ஏற்றுவதில் பிழை. +மறுமுயல தட்டுக." + "மீண்டும் முயல்" + "கருத்துகள்" + "இதுவரை கருத்துகளில்லை. கருத்தை எழுது?" + "வாக்கு தோல்வி" + "இடுகையைப் புத்துணர்வூட்டுவதில் பிழை" + "தகவல்களை ஏற்றுவதில் பிழை. +மறுமுயல தட்டுக." + "காலி" + "NSFW" + + + "கர்மம்: %1$d" + + + "கர்மம்: +%1$d (%2$d + %3$d)" + "https://crowdin.com/" + "சுயவிவரம்" + "குழுசேர்வுகள்" + "பல்ரெட்டிட்" + "உட்பெட்டி" + "மேல்வாக்களித்தீர்" + "கீழ்வாக்களித்தீர்" + "மறைக்கப்பட்டது" + "சேமிக்கப்பட்டது" + "அமைவுகள்" + + + "சந்தாதாரர்கள்: %1$d" + + + "இணைப்பில்: %1$d" + "துணைரெட்டிட் தகவலைப் பெற முடியவில்லை" + "பயனர் தகவலைப் பெற முடியவில்லை" + "ஓரப்பட்டையைப் கொணர முடியவில்லை" + "பல்ரெட்டிட் தகவலைப் பெற முடியவில்லை" + "குழுசேர்" + "குழுவிலகு" + "குழுசேர்ந்தீர்" + "குழுசேர்வு தோல்வி" + "குழுவிலகினீர்" + "குழுவிலகள் தோல்வி" + "பின்தொடர்" + "பின்தொடராதே" + "பின்தொடர்கிறீர்" + "பின்தொடர்தல் தோல்வி" + "பின்தொடர்நீக்கம்" + "பின்தொடர்நீக்கம் தோல்வி" + "துணைரெட்டிட் பதாகைப் படம்" + "எதையும் தேடு" + "இடுகைகள் ஏதுமில்லை" + "சோம்பல் பயன்முறை நின்றது" + "எண்ணங்களை இங்கே பதிவு செய்க" + "உம் ஆர்வமிகு எண்ணம் எங்கே?" + "அனுப்புகிறது" + "கருத்து அனுப்பப்பட்டது" + "இக்கருத்தை அனுப்ப முடியவில்லை" + "பயனர்" + "பொருள் (அதிகபட்சம் 100 வரியுருக்கள்)" + "தகவல்" + "இத்தகவலுக்கு பதிலளிக்க முடியவில்லை" + "இத்தகவலைப் பெறுவதில் தோல்வி" + "யாருக்கு இத்தகவலை நீங்கள் அனுப்ப வேண்டும்?" + "உம் தகவலுக்கு பொருள் வேண்டும்" + "பெருநருக்கு நீங்கள் ஏதாவது சொல்ல வேண்டும்" + "அனுப்புகிறது" + "தகவல் அனுப்பப்பட்டது" + "இத்தகவலை அனுப்ப முடியவில்லை" + "முதலில் துணைரெட்டிட்டைத் தேர்ந்தெடுக்கவும்" + + + "இந்த இடுகைக்கு தலைப்பு தேவை" + "ஏய் இணைப்பு எங்கே?" + "முதலில் படத்தைத் தேர்ந்தெடுப்பீர்" + "இடுகையிடுகிறது" + "இடுகையிட முடியவில்லை" + "படத்தைச் செயலாக்குவதில் பிழை" + "காணொளியைச் செயலாக்குவதில் பிழை" + "பதிவிறக்கம் துவங்கியது. முன்னேற்றத்திற்கு அறிவிப்பைச் சரிபார்." + "கூடுதல் கருத்துகளை ஏற்று" + "ஏற்றம் தோல்வி. மீண்டும் முயல தட்டுக." + "ஏற்றுகிறது" + "தலைப்பு" + "உள்ளடக்கம்" + "துணைரெட்டிட்டைத் தெரிவுசெய்" + "விதிகள்" + "உரலி" + "துனைரெட்டிட்டுகள்" + "பயனர்கள்" + "பல்ரெட்டிட்டுகள்" + "சொற்சரம்" + "தொடுப்பு" + "படம்" + "காணொளி" + "படத்தைத் தேர்ந்தெடு" + "மீண்டும் தேர்ந்தெடு" + "படத்தைப் பெறுவதில் பிழை" + "காணொளியைப் பெறுவதில் பிழை" + "படக்கருவி செயலி ஏதுமில்லை" + "தற்காலிக கோப்பை உருவாக்குவதில் பிழை" + "காணொளி செயல்படுகிறது. காத்திருக்கவும்." + "படம் செயல்படுகிறது. காத்திருக்கவும்." + "கெடுப்பி" + + + "விதி இல்லை" + "விதிகளை ஏற்றுவதில் பிழை. +மீண்டும் முயல தட்டுக." + "விதிகளை ஏற்றுவதில் பிழை" + "இதில் தேடு" + "எல்லா துணைரெட்டிட்டுகளும்" + "சிறந்த" + "சூடான" + "புதிய" + "சீரற்ற" + "உதிக்கின்ற" + "முன்னணி" + "சர்ச்சைக்குரிய" + "ஏற்புடைய" + "கருத்துகள்" + "செயல்பாடு" + "தன்னம்பிக்கை" + "பழைய" + "வினாவிடை" + "நேரலை" + "மணிநேரம்" + "நாள்" + "வாரம்" + "மாதம்" + "வருடம்" + "எல்லா நேரமும்" + "பகிர் செயலை " + "காப்பகமான இடுகை. வாக்கு கிடையாது." + "காப்பகமான இடுகை. கருத்து கிடையாது." + "காப்பகமான இடுகை. பதிலளிப்பு கிடையாது." + "பூட்டப்பட்ட இடுகை. கருத்து கிடையாது." + "பூட்டப்பட்ட இடுகை. பதிலளிப்பு கிடையாது." + "சொற்சரம்" + "தொடுப்பு" + "படம்" + "காணொளி" + "காட்சியகம்" + "சிறந்த" + "தேடு" + "காணொளியை இடுகையிடுகிறது" + "படத்தை இடுகையிடுகிறது" + "காத்திருக்கவும்" + + + "கணக்கைச் சேர்" + "அநாமதேய" + "வெளியேறு" + "உள்நுழைய இங்கே அழுத்து" + "முதலில் உள்நுழை" + "இடுகை சேமிக்கப்பட்டது" + "இடுகையைச் சேமிக்க இயலவில்லை" + "இடுகை அசேமிக்கபட்டது" + "இடுகையை அசேமிக்க இயலாது" + "இடுகை மறைக்கப்பட்டது" + "இடுகையை மறைக்க இயலாது" + "இடுகை அமறைக்கப்பட்டது" + "இதை விருப்பமாக்குவதில் தோல்வி" + "இதை விருப்பம்நீக்குவதில் தோல்வி" + "இடுகையை மறைவுநீக்க இயலவில்லை" + "இந்த இடுகையை அழி" + "இக்கருத்தை அழி" + "நீங்கள் உறுதியா?" + "திருத்து" + "அழி" + "நீக்கப்பட்ட கருத்தைப் பார்" + "நீக்கப்பட்ட கருத்தைப் பெறுகிறது" + "நீக்கப்பட்ட கருத்தைக் கண்டறிய முடியவில்லை" + "நீக்கப்பட்ட இடுகையைப் பெறுகிறது" + "நீக்கப்பட்ட இடுகையைப் பெற முடியவில்லை" + "ரத்துசெய்" + "சரி" + "திருத்தம் வெற்றி" + "அழித்தல் வெற்றி" + "அழித்தல் தோல்வி" + "NSFW குறித்தல் வெற்றி" + "NSFW குறித்தல் தோல்வி" + "NSFW குறிநீக்கல் வெற்றி" + "NSFW குறிநீக்கல் தோல்வி" + "எல்லா கருத்துகளையும் உலாவ இங்குச் சொடுக்கு" + "கணக்கு" + "புதிய தகவல்" + "துணைரெட்டிட்" + "விருது" + + + "%1$d புதிய தகவல்கள்" + "கணக்கு" + "இடுகை" + "விருப்பத்தேர்வுகள்" + "கணக்கு நிலைமாறியது. ஆக மற்றவெல்லா பக்கங்களும் சென்றது." + "அறிவிப்பு" + "அறிவிப்புகளை இயக்கு" + "அறிவுப்புகள் இடைவேளையைச் சரிபார்" + "தோற்றம்" + "இடைமுகம்" + "சைகைகளும் பொத்தான்களும்" + "காணொளி" + "கானொளி தானியக்கம்" + "தானியங்கும் கானொளிகளை ஒலியடக்கு" + "NSFW காணொளிகளைத் தானியக்கு" + "எல்லா பக்கங்களுக்கும் செயல்படுத்தாதே" + "அடிப்புற வழிசெழுத்தலை இயக்கு" + "இடுகையிட்டு கருத்தளி" + "வலதில் வாக்குப் பொத்தான்கள்" + "காணொளிகளை ஒளியடக்கு" + "NSFW காணொளிகளை ஒலிமறு" + "காணொளி இயக்கியில் வழிசெலுத்தல் பட்டையைப் புறக்கணி" + "வெளியேற உறுதிசெய்" + "கருத்து" + "உயர்மட்ட கருத்துகளை முதலில் காட்டு" + "கருத்து வகுப்பானைக் காட்டு" + "கருத்து கருவிப்பட்டையை காட்ட/மறைக்க சொடுக்கு" + "கருத்து கருவிப்பட்டை இயல்பாக மறைந்திருக்கும்" + "அறுதியான வாக்கெண்ணிக்கை காட்டு" + "நேர வடிவம்" + "இடுகை" + "இயல்புநிலை இடுகை தளவமைப்பு" + "வகுப்பானைக் காட்டு" + "சிறுபடத்தை இடதில் காட்டு" + "கருத்துகளில் தட்டு மற்றும் நீண்டழுத்தை பண்டமாற்று" + "பின்செல்ல வலப்புறம் தேய்" + "எல்லா பக்கங்களுக்கும் செயல்படாது" + "அடிப்புற வழிசெழுத்தல் பட்டையை பூட்டு" + "எழுத்துரு" + "எழுத்துரு முன்னோட்டம்" + "எழுத்துரு" + "தலைப்பு" + "உள்ளடக்கம்" + "எழுத்துரு குடும்பம்" + "தலைப்பு எழுத்துரு குடும்பம்" + "உள்ளடக்கம் எழுத்துரு குடும்பம்" + "எழுத்துரு அளவு" + "தலைப்பு எழுத்துரு அளவு" + "உள்ளடக்கம் எழுத்துரு அளவு" + "NSFWஐ இயக்கு" + "NSFW படங்களை மங்கலாக்கு" + "கெட்டுப்பி படங்களை மங்காக்கு" + "இதுபற்றி" + "ஒப்புகை" + "உருவடி முன்புலம்" + "உருவடி பின்புலம்" + "குறுக்கிடுகை படவுரு" + "ஏவூர்தி படவுரு" + "மெட்டீரியல் படவுருக்கள்" + "திறந்த மூலம்" + "உமக்குப் பிடித்திருந்தால் கிட்ஹபில் இச்செயலியை நட்சத்திரமிடு" + "கூகுள் பிளேயில் மதிப்பிடு" + "எனக்கு 5-நட்சத்திர மதிப்பீடு கொடுங்கள் நான் உண்மையில் மகிழ்ச்சியாக இருப்பேன்" + "மின்னஞ்சல்" + "ரெட்டிட் கணக்கு" + "u/Hostilenemy" + "துணைரெட்டிட்" + "r/Infinity_For_Reddit" + "பகிர்" + "இன்புறுகிறீர்களெனில் மற்ற மக்களுக்கும் இச்செயலியை அனுப்புக" + "பதிப்பு %s" + "தனிப்பயனாக்கம்" + "ஒளிர்ந்த தோற்றம்" + "இருண்ட தோற்றம்" + "கருந்தோற்றம்" + "தோற்றங்களை நிர்வகி" + "மேம்பட்ட" + "தரவுதளத்தில் அனைத்து துணைரெட்டிட்களை அழி" + "தரவுதளத்தில் அனைத்து பயனர்களை அழி" + "தரவுதளத்தில் அனைத்து வரிசை வகைகளை அழி" + "தரவுதளத்தில் அனைத்து இடுகை தளவமைப்புகளை அழி" + "தரவுதளத்தில் அனைத்து தோற்றங்களை அழி" + "எல்லா அமைவுகளையும் அகரமாக்கு" + "தாவல் 1" + "தாவல் 2" + "தாவல் 3" + "தலைப்பு" + "வகை" + "தொடுப்பைப் பெற முடியவில்லை" + "விலகவா?" + "கைவிடவா?" + "ஆம்" + "இல்லை" + "பகிர்" + "மின்னஞ்சல் நுகர்வி ஏதுமில்லை" + "செயலி ஏதுமில்லை" + "கருத்து சேமிக்கப்பட்டது" + "கருத்தைச் சேமிக்க இயலவில்லை" + "கருத்து சேமிப்புநீக்கப்பட்டது" + "கருத்தை சேமிப்புநீக்க இயலவில்லை" + "பிடித்தவை" + "அனைத்தும்" + "அட்டை தளவமைப்பு" + "கச்சிதமான தளவமைப்பு" + "இப்போது தான்" + "1 நிமிடம்" + + + "%1$d நிமிடங்கள்" + "1 மணிநேரம்" + + + "%1$d மணிநேரம்" + "நேற்று" + + + "%1$d நாட்கள்" + "1 மாதம்" + + + "%1$d மாதங்கள்" + "1 வருடம்" + + + "%1$d வருடங்கள்" + "பல்ரெட்டிட் தரவைப் பெருவதில் பிழை" + "பல்ரெட்டிட்களை ஒத்திசைக்க முடியவில்லை" + "துணைரெட்டிட் பெயரைப் பெறுவதில் பிழை" + "இடுகை தொடுப்பைப் பகிர்" + "பட தொடுப்பைப் பகிர்" + "காணொளி தொடுப்பைப் பகிர்" + "தொடுப்பைப் பகிர்" + "இடுகை தொடுப்பை நகலெடு" + "பட தொடுப்பைப் நகலெடு" + "காணொளி தொடுப்பைப் நகலெடு" + "தொடுப்பைப் நகலெடு" + "நகலெடுக்கட்டது" + "தொடுப்பை நகலெடுக்க முடியவில்லை" + "நகலெடு" + "அனைத்தையும் நகலெடு" + "வெளியேறவா?" + "ஒளிர்ந்த தோற்றம்" + "இருண்ட தோற்றம்" + "பெயர் (அதிகபட்சம் 50 வரியுருக்கள்)" + "விவரிப்பு" + "தனிப்பட்ட" + "பெயர் எங்கே?" + "இப்பல்ரெட்டிட்டை உருவாக்க இயலா" + "இப்பல்ரெட்டிட் ஏற்கனவே உள்ளது" + "இப்பல்ரெட்டிட்டைத் திருத்த இயலா" + + + "அழித்தல் வெற்றி" + "அழித்தல் தோல்வி" + "நீங்கள் உறுதியா?" + "NSFWஐ இயக்கு" + "NSFWஐ முடக்கு" + "படத்தைச் சேமிக்கவியலா" + "படத்தைச் சேமிக்கிறது. காத்திருக்கவும்." + "இத்தோற்றத்தின் பெயரை மாற்ற தட்டு." + "ஒளிர்ந்த தோற்றமாக அமை" + "இருண்ட தோற்றமாக அமை" + "கருந்தோற்றமாக அமை" + "இடுகை தலைப்பு நிறம்" + "இடுகை உள்ளடக்க நிறம்" + "கருத்து நிறம்" + "பொத்தான் உரை நிறம்" + "தொடுப்பு நிறம்" + "பெற்ற தகவல் உரை நிறம்" + "அனுப்பிய தகவல் உரை நிறம்" + "பின்புல நிறம்" + "பெற்ற தகவல் பின்புல நிறம்" + "அனுப்பிய தகவல் பின்புல நிறம்" + "அடிப்புற வழிசெழுத்தல் பட்டை நிறம்" + "முதன்மை படவுரு நிறம்" + "அடிப்புற வழிசெழுத்தலை பட்டை படவுரு நிறம்" + "இடுகை படவுரு மற்றும் தகவல் நிறம்" + "கருத்து படவுரு மற்றும் தகவல் நிறம்" + "மிதக்குஞ்செயல் பொத்தான் படவுரு நிறம்" + "தகவல் அனுப்புப் படவுரு நிறம்" + "கருவிப்பட்டை முதன்மை உரை மற்றும் படவுரு நிறம்" + "மேல்வாக்களித்த நிறம்" + "கீழ்வாக்களித்த நிறம்" + "இடுகை வகை பின்புல நிறம்" + "இடுகை வகை உரை நிறம்" + "NSFW பின்புல நிறம்" + "விருதுகள் பின்புல நிறம்" + "விருதுகள் உரை நிறம்" + "காப்பகமானவை படவுரு நிறம்" + "பூட்டப்பட்டது படவுரு நிறம்" + "குறுக்கிடுகை படவுரு நிறம்" + "பயனர்பெயர் நிறம்" + "வகுப்பான் நிறம்" + "வாக்கு மற்றும் பதிலளி கிடைக்கவில்லை பொத்தான் நிறம்" + "கருத்து செங்குத்துப்பட்டை நிறம் 1" + "கருத்து செங்குத்துப்பட்டை நிறம் 2" + "கருத்து செங்குத்துப்பட்டை நிறம் 3" + "கருத்து செங்குத்துப்பட்டை நிறம் 4" + "கருத்து செங்குத்துப்பட்டை நிறம் 5" + "வழிசெலுத்தல் அலமாரி நிறம்" + "இருண்ட வழிசெழுத்தல் பட்டை படவுரு நிறம்" + "ஆண்டிராய்டு 8.0 அல்லது மேற்பட்டவைக்கு மட்டுங்கிடைக்கும்." + "ஆண்டிராய்டு 6.0 அல்லது மேற்பட்டவைக்கு மட்டுங்கிடைக்கும்." + "உமது தோற்றங்கள்" + "இத்தோற்றத்தின் பெயரென்ன?" + "தோற்றம் பெயர்" + "வெள்ளை" + "இருண்ட வெள்ளை" + "கரு வெள்ளை" + "சிகப்பு" + "இருண்ட சிகப்பு" + "கருஞ்சிகப்பு" + "தோற்றப்பெயரைத் திருத்து" + "தோற்றத்தைத் திருத்து" + "தோற்றத்தை அழி" + + + "%1$s-ஐ அழிப்பதிலுறுதியா?" + "தோற்றத்தைப் பகிர்" + "பெயரை மாற்று" + "இத்தோற்றத்தைக் கண்டறிய முடியவில்லை" + "தோற்றத்தை ஏற்றுமதிசெய்" + "நகலகத்தில் தரவைக்கண்டறிய முடியவில்லை" + "தோற்றம் ஏற்றுமதி வெற்றி" + "தோற்றநகல் கண்டறியப்பட்டது" + "மறுபெயரிடு" + "நிறத்தெரிவி" + "செல்லாத நிறம்" + "அனைத்து துணைரெட்டிட்களை அழித்தல் வெற்றி" + "அனைத்து பயனர்களை அழித்தல் வெற்றி" + "அனைத்து வரிசை வகைகளை அழித்தல் வெற்றி" + "அனைத்து இடுகை தளவமைப்புகளை அழித்தல் வெற்றி" + "அனைத்து தோற்றங்களை அழித்தல் வெற்றி" + "அனைத்து அமைவுகளை அகரமாக்கல் வெற்றி" + "முதன்மை உரை" + "இது ஓர் இடுகை" + "இடுகை" + "4 விருதுகள்" + "பல்ரெட்டிட்டைத் திருத்து" + "பல்ரெட்டிட்டை அழி" + + + "%1$d விருதுகள்" + "1 விருது" + "புகாரளி" + "புகாரளிக்கிறது" + "புகாரளிக்கப்பட்டது" + "புகார் தோல்வி" + "நீ காரணத்தைத் தேர்ந்தெடுக்கவில்லை" + "வீண் ஆனது" + "பதிப்புரிமைச் சிக்கல் கொண்டுள்ளது" + "சிறார் ஆபாசவியல் கொண்டுள்ளது" + "வன்கொடுமை உள்ளடக்கம் கொண்டுள்ளது" + "வீடு" + "பிரபலமான" + "அறிவிப்புகள்" + "தகவல்கள்" + "தகவல்" + "படங்களை ஏற்ற முடியவில்லை" + "காணொளி தடத்தைப் பதிவிறக்கிறது" + "ஒலி தடத்தைப் பதிவிறக்கிறது" + "காணொளியைச் சேமிக்கிறது" + "பதிவிறக்கப்பட்டது" + "சுவரொட்டி அமைக்கப்பட்டது" + "சுவரொட்டியை அமைக்க முடியவில்லை" + "முகப்புத்திரைக்கு அமை" + "பூட்டுத்திரைக்கு அமை" + "இரண்டிர்க்கும் அமை" + "இயல்புநிலை" + "குறுக்கிடுகை" + "விருதளி" + "குறுக்கிடுகையிடு" + "விருதளி" + "இடுகைகள்" + "உள்துழைந்த பயனர்களுக்கு மட்டும்" + "மாற்றங்களைப் காண செயலியை மறுதுவக்கு" + "தாவல் எண்ணிக்கை" + "தாவல் பெயர்களைக் காட்டு" + "மேலும் கீற்றுகள்" + "பதிவிறக்குமிடம்" + "படம் பதிவிறக்குமிடம்" + "அசைபடம் பதிவிறக்குமிடம்" + "காணொளி பதிவிறக்குமிடம்" + "தேய்த்தல் செயல்" + "கீற்றுகளுக்கிடையே தேய்ப்பதை முடக்கு" + "தேய்த்தல் செயலை இயக்கு" + "புத்துணர்வூட்ட இழு" + "பாதுகாப்பு" + "கருவிப்பட்டையை மறைக்க நீண்டழுத்து" + "கருவிப்பட்டையை இயல்பாகவே மறை" + "முதன்மை பக்கம்" + "பிற பக்கங்கள்" + "விருப்ப எண்ணிக்கை" + "விருப்பம் 1" + "விருப்பம் 2" + "விருப்பம் 3" + "விருப்பம் 4" + "தரவு சேமிப்பு பயன்முறை" + "மொழிபெயர்ப்பு" + "தேசிய கொடிகள்" + "பதிவிறக்கப்பட்டது" + "பதிவிறக்கம் தோல்வி" + "பெரிய" + "சிறிய" + "தொடுப்பைப் புகுத்து" + "உரை" + "தொடுப்பு" + "பூட்டவிழ்" + "இடுகையைச் சமர்ப்பி" + "புத்துணர்வூட்டு" + "வகைப்படுத்தல் வகையை மாற்று" + "இடுகை தளவமைப்பை மாற்று" + "விருதளிக்கவா?" + "அநாமதேய" + "விருது அளிக்கப்பட்டது" + "தோல்வியுற்றது" + "எச்சரிக்கை" + "இது ஓர் NSFW துணைரெட்டிட்." + "இப்பயனர் NSFW உள்ளடக்கம் கொண்டுள்ளார்" + "நிராகரி" + "விலகு" + "துணைரெட்டிட்டுக்குச் செல்" + "பயனருக்குச் செல்" + "பெயர்" + "சீரற்ற" + "சீரற்ற துணைரெட்டிட்" + "சீரற்ற NSFW கணக்கு" + "சீரற்ற இடுகை" + "சீரற்ற NSFW இடுகை" + "பின்னர் மீண்டும் முயல்" + "பதிவிறக்குகிறது" + "r/all மற்றும் r/popular" + "இதர" + "துணைரெட்டிட்டுகளை மறை" + "r/popular மற்றும் r/all இல்" + "காணொளி தரத்தைத் தேர்ந்தெடு" + "துணைரெட்டிட் விளக்கத்தை மறை" + "இடப்புறம் தேய்" + "வலப்புறம் தேய்" + "மொழி" + "வடிக்கப்பட்ட இடுகைகள்" + "இடுகை வடிகட்டி" + "பயனர்கள்" + "பல்ரெட்டிட்டைத் தேர்ந்தெடு" + "தரவுத்தளத்தில் சேமி" + "எல்லா தகவல்களையும் வாசி" + "பல்ரெட்டிட்டுக்குச் சேர்" + "துணைரெட்டிட்டுகளைத் தேடு" + "பயனர்களைத் தேடு" + "காட்சியகம்" + "தனியுரிமைக் கொள்கை" + "தரவுத்தளத்தில் எல்லா வாசித்த இடுகைகளையும் அழி" + "இடுகை வடிகட்டி" + "தேடல் வரலாற்றை இயக்கு" + "இடுகை வரலாறு" + "இடுகைகளைப் வாசித்ததாக்கு" + "வாக்களித்தபின் இடுகைகளை வாசித்ததாக்கு" + "வாசித்த இடுகைகளை தானாக மறை" + "வரிசைப்படுத்தல் வகை" + "வரிசைப்படுத்தல் வகையைச் சேமி" + "தொடுப்பைத் திற" + "துணைரெட்டிட்டுகள் மற்றும் பயனர்களைத் தேர்ந்தெடு" + "வாசித்த இடுகைகளை மறை" + "இடுகைகளை வடிகட்டு" + "NSFW மட்டும்" + "கெடுப்பி மட்டும்" + "முகப்பு" + "துணைரெட்டிட்: %1$s" + "துணைரெட்டிட்" + "பயனர்: %1$s" + "பயனர்" + "பல்ரெட்டிட்: %1$s" + "பல்ரெட்டிட்" + "தேடு" + "துணைரெட்டிட்" + "பயனர்" + "எல்லா தகவல்களையும் வெற்றிகரமாக வாசித்தாச்சு" + "எல்லா தகவல்களையும் வாசிக்க இயலவில்லை" + "பயனரைத் தெரிவுசெய்" + "இடுகை வகையை மறை" + "விருது எண்ணிக்கையை மறை" + "வாக்கெண்ணிக்கையை மறை" + "கருத்தெண்ணிக்கையை மறை" + "காட்சியக தளவமைப்பு" + "அட்டை தளவமைப்பு 2" + "வாக்களி" + "தொடுப்பைப் பகிர்" + "தொடுப்பை நகலெடு" + "அமைவுகளைப் பிரதியெடு" + "அமைவுகளை மீட்டமை" + "இடுகைகளுக்கிடையே தேய்" + "வழிசெலுத்தல் அலமாறி" + "சாதன இயல்புநிலை" + "மின்கல சேமிப்பானால் அமைப்பட்டது" + "தற்போதய பயனர்" + "துனைரெட்டிட்டில் சேருவதன் மூலம் துவங்கு!" + "கோப்பை அணுக முடியவில்லை" + "இதை மீண்டும் காட்டாதே" + "தொடரவும்" + "ஒருபோதுமில்லை" + "சாதாரணம்" + "மிகப்பெரிது" + "மிகமிகப்பெரிது" + "இயல்புநிலை" + "மேல்வாக்களி" + "கீழ்வாக்களி" + "தேர்ந்தெடு" + "இத்துணைரெட்டிட்டை விலக்கு" + "இப்பயனரை விலக்கு" + "தலைப்பைப் பரிந்துரை" + "தலைப்பைப் பரிந்துரைப்பதில் தோல்வி" + "பயன்குறிப்புகளை அழி" + "சிதைவறிக்கைகள்" + "ஆபத்தானது" + "NSFWஐ என்றென்றும் முடக்கு" + "சேமி" + "சேமிக்கா" + + + "சிதைவறிக்கைகள் அழிக்கப்பட்டன" + "பதிலளி" + "பிரபலமாகும்" + "இடுகை தொடுப்பைப் பகிர்" + "பிரபலமாகும்" + "காட்சியகம்" + "ரெட்டிட்" + "பல்ரெட்டிட்டைக் காட்டு" + "தானாக" + "பதிவேற்றிய படங்கள்" + "படத்தைத் தேர்ந்தெடு" + "கைப்பற்று" + "பதிவேற்றுகிறது" + "படம் பதிவேற்றம் வெற்றி. பதிவேற்றிய படங்களைப் பார்க்க படம் பொத்தானை மீண்டும் சொடுக்கு." + "படத்தைப் பதிவேற்றவியலா" + "கருத்துகளைத் தேடு" + "ஒரு படம் இன்னும் பதிவேறுகிறது. காத்திருக்கவும்." + "விக்கி" + "இடுகை விவரங்கள்" + "பாதுகாப்பான பயன்முறை" + "கைவிடு" + "விக்கியை ஏற்றுவதில் பிழை" + "இத்துனைரெட்டிட்டுக்கு விக்கி பக்கம் இல்லை" + "விக்கிக்குச் செல்" + "பற்றி" + "வழிசெலுத்தல் அலமாரியைத் திற" + "செயலி பூட்டு" + "செயலி பூட்டு நேரமுடிந்தது" + + + "வெளிப்புற உலாவி" + "தனிப்பயன் கீற்று" + "காணொளியைப் பெரிதாக்க கிள்ளு" + "பரீட்சார்ந்த அம்சம்" + "மேலே செல்" + "உடனடியாக" + "1 நிமிடம்" + "2 நிமிடங்கள்" + "5 நிமிடங்கள்" + "10 நிமிடங்கள்" + "15 நிமிடங்கள்" + "20 நிமிடங்கள்" + "30 நிமிடங்கள்" + "1 மணிநேரம்" + "2 மணிநேரம்" + "3 மணிநேரம்" + "4 மணிநேரம்" + "5 மணிநேரம்" + "6 மணிநேரம்" + "12 மணிநேரம்" + "24 மணிநேரம்" + \ No newline at end of file diff --git a/app/src/main/res/values-v31/styles.xml b/app/src/main/res/values-v31/styles.xml new file mode 100644 index 00000000..d0bf504a --- /dev/null +++ b/app/src/main/res/values-v31/styles.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index c41311df..2fce5be3 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -44,6 +44,7 @@ @string/post_layout_card @string/post_layout_card_2 + @string/post_layout_card_3 @string/post_layout_compact @string/post_layout_gallery @@ -51,6 +52,7 @@ 0 3 + 4 1 2 @@ -59,6 +61,7 @@ @string/link_post_layout_auto @string/post_layout_card @string/post_layout_card_2 + @string/post_layout_card_3 @string/post_layout_compact @string/post_layout_gallery @@ -67,6 +70,7 @@ -1 0 3 + 4 1 2 @@ -457,10 +461,12 @@ English Française Deutsche + Ελληνικά हिंदी Magyar Italiana 日本語 + 한국인 Polskie Português Português (BR) @@ -468,6 +474,7 @@ русский Soomaali Español + தமிழ் Türkçe Українська Tiếng Việt @@ -482,10 +489,12 @@ en fr de + el hi hu it ja + ko pl pt pt-rBR @@ -493,6 +502,7 @@ ru so es + ta tr-rTR uk vi diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 074ab268..85e66c59 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,7 +3,7 @@ #0336FF #002BF0 #FF1868 - #88000000 + #00000000 #FFFFFF #000000 #FFFFFF diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5e12294b..963570d7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - + Eternity Login @@ -46,6 +46,9 @@ Edit Profile Poll Post History + Subscription + Comment Filter + Customize Post Filter Open navigation drawer Close navigation drawer @@ -97,6 +100,7 @@ Playback Speed Contact Mods More Options + Add to Home screen Error occurred when parsing the JSON response Error Retrieving the token @@ -270,6 +274,9 @@ Search in All communities + Confirm + Are you sure you want to delete all recent search queries? + Active Hot New @@ -655,6 +662,7 @@ Easier to Watch in Full Screen Hide FAB in Post Feed Comment Divider Type + Comment Filter Cannot get the link @@ -693,6 +701,7 @@ Compact Layout Gallery Layout Card Layout 2 + Card Layout 3 Just Now 1 Minute @@ -806,6 +815,10 @@ Applied to: Post background and message background Read Post Card View Background Color Applied to: Read Post background + Filled Card View Background Color + Applied to: Background of a post in a filled card view, some edit text fields + Read Post Filled Card View Background Color + Applied to: Background of a read post in a filled card view Comment Background Color Applied to: Comment background Fully-Collapsed Comment Background Color @@ -1143,18 +1156,31 @@ What is the name of this post filter? \'%1$s\' Already Exists Override it? - Apply to + Apply to Home Community: %1$s Community + All Communities User: %1$s User + All users Multicommunity: %1$s Multicommunity + All Multicommunities Search Community User Leave it blank to apply this post filter to all the communities / users / multicommunities + Click here to apply it to some post feeds + and %1$d more + + Exclude keywords (key1,key2) + Comment Filter Name + What is the name of this comment filter? + \'%1$s\' Already Exists + Override it? + Applied to all subreddits + and %1$d more You are doing this too frequently. Try again later. This is Reddit API\'s rate limit. Read all messages successfully @@ -1173,7 +1199,7 @@ Start by joining a community! This multicommunity does not have a community! - Successfully exported settings to the destination directory. The password of the generated zip file is 123321. Please don\'t modify the zip file. + Successfully exported settings to the destination directory. Could not create backup zip in the destination directory Could not backup some settings but others were successfully exported to the destination directory Successfully restored settings. Restart the app to see the changes. @@ -1314,12 +1340,8 @@ Handle Link Invalid link - Unexpected intent action: %1$s - Enable random adaptation Media includes video tracks, but none are playable by this device Media includes audio tracks, but none are playable by this device - Permission to access storage was denied - One or more sample lists failed to load Volume Up Volume Off @@ -1334,8 +1356,48 @@ Notification permission is not granted Settings - Important Notice Regarding Reddit API Changes - Starting from July 1st, 2023, Reddit API will be pay-per-use for 3rd-party clients, which include Infinity for Reddit. The announcement from Reddit can be found here: %1$s\n\nIn order to survive this change, Infinity will become a subscription-only app after July 1st. You can learn more about the changes in this post: %2$s\n\nIt\'s required for you to update Infinity after July 1st so that you will get the new version with subscription options. None of the previous versions (including this one) will work after July 1st. But due to a tight timeline Reddit gave, the update may not be available immediately on July 1st since it requires proper testing. Thank you for your understanding! + Welcome to Infinity for Reddit, your gateway to a whole new dimension of Reddit browsing! + Before you dive into the countless possibilities this app offers, + I want to be upfront and transparent about a significant change I\'ve implemented to ensure the best possible service for you. + \n\nFrom now on, you will need a monthly subscription to access the Reddit API within Infinity for Reddit and + this is because Reddit has started charging for API access since July 1st, 2023. + \n\nAll the tiers work the same. If you want to support Infinity, you can subscribe to a higher tier. + Most of the money from the lowest tier goes to Reddit. + + Monthly + Yearly + Weekly + Billing service unavailable on device. + The developer made some errors. Not your fault. + Fatal error during the API action. + The requested feature is not supported by the Play Store on the current device. + The purchase failed because the item is already owned. + The requested product is not available for purchase. + A network error occurred during the operation. + The app is not connected to the Play Store service via the Google Play Billing Library. + The service is currently unavailable. + Transaction was canceled by the user. + Bronze + Silver + Gold - Perfect Choice! + Platinum + Diamond + Infinity + Cannot acknowledge purchase + Failed to connect to the billing system + Connecting to the billing system. Please wait. + Thank you for your subscription + Load subscription options + Acknowledging your subscription. Please wait. + Oops, there was an error when acknowledging your purchase. If this problem persists for three days, you will automatically get a refund.\nDon\'t worry, you can still enjoy Infinity for Reddit. + Continue to app + Already paid for the subscription? + Restore subscription purchase + + Please re-login your account + Infinity for Reddit with subscription uses a new API key from Reddit and you have to re-login to continue using the app.\n\nJust + open the navigation drawer and click your account header and select \"Add an account\" to login to Reddit using the same account again. + Otherwise, Infinity may not load posts at all. Sorry for the inconvenience. I understand Instance URL The URL of you preferred Lemmy instance with or without the https:// prefix diff --git a/app/src/main/res/xml/main_preferences.xml b/app/src/main/res/xml/main_preferences.xml index 32445142..8160f20c 100644 --- a/app/src/main/res/xml/main_preferences.xml +++ b/app/src/main/res/xml/main_preferences.xml @@ -67,6 +67,11 @@ app:icon="@drawable/ic_filter_24dp" app:title="@string/settings_post_filter_title" /> + +